Imported Upstream version 1.7.6 upstream/1.7.6
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:05 +0000 (11:15 +0900)
101 files changed:
AUTHORS
NEWS
README
configure
configure.ac
ltmain.sh
m4/libtool.m4
src/extensions/Makefile.am
src/extensions/Makefile.in
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/compress/compressscript.cc
src/extensions/compress/fstcompress-main.cc
src/extensions/compress/fstcompress.cc
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/farscript.cc
src/extensions/far/stlist.cc
src/extensions/far/sttable.cc
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/pdt/Makefile.am
src/extensions/pdt/Makefile.in
src/extensions/python/Makefile.am
src/extensions/python/Makefile.in
src/extensions/python/cpywrapfst.pxd
src/extensions/python/pywrapfst.cpp [moved from src/extensions/python/pywrapfst.cc with 80% similarity]
src/extensions/python/pywrapfst.pxd
src/extensions/python/pywrapfst.pyx
src/extensions/python/utility.pxd [new file with mode: 0644]
src/extensions/special/Makefile.am
src/extensions/special/Makefile.in
src/include/Makefile.am
src/include/Makefile.in
src/include/fst/accumulator.h
src/include/fst/add-on.h
src/include/fst/arc-map.h
src/include/fst/arc.h
src/include/fst/bi-table.h
src/include/fst/compact-fst.h
src/include/fst/complement.h
src/include/fst/connect.h
src/include/fst/determinize.h
src/include/fst/disambiguate.h
src/include/fst/edit-fst.h
src/include/fst/equal.h
src/include/fst/expander-cache.h
src/include/fst/expectation-weight.h
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/compress/compressscript.h
src/include/fst/extensions/compress/gzfile.h [deleted file]
src/include/fst/extensions/far/create.h
src/include/fst/extensions/far/print-strings.h
src/include/fst/extensions/mpdt/mpdtscript.h
src/include/fst/extensions/ngram/bitmap-index.h
src/include/fst/extensions/special/phi-fst.h
src/include/fst/float-weight.h
src/include/fst/fst-decl.h
src/include/fst/fst.h
src/include/fst/label-reachable.h
src/include/fst/lookahead-matcher.h
src/include/fst/matcher-fst.h
src/include/fst/matcher.h
src/include/fst/minimize.h
src/include/fst/product-weight.h
src/include/fst/push.h
src/include/fst/queue.h
src/include/fst/randgen.h
src/include/fst/rational.h
src/include/fst/relabel.h
src/include/fst/replace.h
src/include/fst/script/fst-class.h
src/include/fst/shortest-distance.h
src/include/fst/signed-log-weight.h
src/include/fst/state-map.h
src/include/fst/state-table.h
src/include/fst/string.h
src/include/fst/symbol-table-ops.h
src/include/fst/symbol-table.h
src/include/fst/test-properties.h
src/include/fst/test/algo_test.h
src/include/fst/topsort.h
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/fst.cc
src/lib/symbol-table-ops.cc
src/lib/symbol-table.cc
src/script/Makefile.am
src/script/Makefile.in
src/test/weight_test.cc

diff --git a/AUTHORS b/AUTHORS
index 6840e8b..f9a89fe 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,6 @@
-Principal Contacts:
+Google, Inc.
+
+Principal developers:
 
 Cyril Allauzen     <allauzen@google.com>
 Michael Riley      <riley@google.com>
@@ -25,4 +27,5 @@ Jeffrey Sorensen
 Richard Sproat
 Ananda Theertha Suresh
 Terry Tai
+Lawrence Wolf-Sonkin
 Ke Wu
diff --git a/NEWS b/NEWS
index 5e65965..fe0577b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,9 @@
 OpenFst: Release 1.7
+   * Adds MakeArcMapFst (1.7.6)
+   * Adds RealWeight and Real64Weight (1.7.6)
+   * Adds a new, idiomatic SymbolTable iterator interface (1.7.6)
+   * Improves symbol table lifetime management in pywrapfst (1.7.6)
+   * Improves the design of the FST class hierarchy in pywrapfst (1.7.6)
    * Removes unnecessary template parameters in constructors (1.7.5)
    * Converts RmEpsilonFstOptions from class to struct (1.7.5)
    * Eliminates redundant checks in Minimize (1.7.5)
@@ -35,7 +40,7 @@ OpenFst: Release 1.6
    * Fixed PROGRAM_FLAGS documentation string in binaries (1.6.8)
    * Fixed handling of symbol tables in EpsNormalize (1.6.8)
    * Fixed error reporting when FST arc type unknown (1.6.8)
-   * The `first_path` option to ShortestPath is now optimal for A* (1.6.7)
+   * The first_path option to ShortestPath is now optimal for A* (1.6.7)
    * Renames SymbolTable::kNoSymbol to kNoSymbol (1.6.7)
    * Exposes PowerMapper to the scripting API (1.6.7)
    * Fixes linking of the special SOs (1.6.7)
@@ -96,8 +101,8 @@ OpenFst: Release 1.5
      pointers where possible, and fixed reference-counting bugs (1.5.1)
    * When calling DeleteStates on a MutableFst with a shared impl, the impl
      is set to a new empty impl rather than copying and deleting (1.5.1)
-   * Prepended `Pdt` to the Expand libraries and classes in the PDT
-     extension, and prepended `MPdt` to the Expand libraries and classes
+   * Prepended Pdt to the Expand libraries and classes in the PDT
+     extension, and prepended MPdt to the Expand libraries and classes
      in the MPDT extension, so that both can be used in the same compilation
      unit (1.5.1)
    * Added option to PDT Replace for compiling a strongly-regular RTN into a
diff --git a/README b/README
index 15d352a..c7dbd3c 100644 (file)
--- a/README
+++ b/README
@@ -18,6 +18,7 @@ INSTALLATION:
   --enable-compress        Enable compression extension (def: no)
   --enable-const-fsts      Enable ConstFst extensions (def: no)
   --enable-far             Enable FAR extensions (def: no)
+  --enable-fsts            Enable all FST SO extensions (def: no)
   --enable-grm             Enable all dependencies of OpenGrm (def: no)
   --enable-linear-fsts     Enable LinearTagger/ClassifierFst extensions (def: no)
   --enable-lookahead-fsts  Enable LookAheadFst extensions (def: no)
@@ -60,7 +61,7 @@ USAGE:
   or /usr/local/include/fst/extensions.
 
 BUILDING WITH BAZEL:
-  As of release 1.7.2 it is possible to build the core library and binaries as
+  Release 1.7.2 provides the ability to build the core library and binaries as
   well as several extensions with Bazel and to depend on OpenFst as an
   external dependency in other projects compiled with Bazel. Please refer to
   https://bazel.build for information on using Bazel. OpenFst can be compiled
@@ -72,6 +73,8 @@ BUILDING WITH BAZEL:
 
   $ bazel test //:all
 
+  The Bazel build-file is provided as-is.
+
 DOCUMENTATION:
   See www.openfst.org for general documentation.
   See ./NEWS for updates since the last release.
index 95d67eb..58f0e43 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.5.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.7.6.
 #
 # 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.5'
-PACKAGE_STRING='OpenFst 1.7.5'
+PACKAGE_VERSION='1.7.6'
+PACKAGE_STRING='OpenFst 1.7.6'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -640,6 +640,8 @@ DL_LIBS
 libfstdir
 HAVE_GRM_FALSE
 HAVE_GRM_TRUE
+HAVE_FSTS_FALSE
+HAVE_FSTS_TRUE
 HAVE_SCRIPT_FALSE
 HAVE_SCRIPT_TRUE
 HAVE_BIN_FALSE
@@ -826,6 +828,7 @@ enable_pdt
 enable_python
 enable_special
 enable_bin
+enable_fsts
 enable_grm
 with_libfstdir
 '
@@ -1395,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.5 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.7.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1466,7 +1469,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.5:";;
+     short | recursive ) echo "Configuration of OpenFst 1.7.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1497,6 +1500,7 @@ Optional Features:
   --enable-python         enable Python extensions
   --enable-special        enable special-matcher extensions
   --enable-bin            enable fst::script and command-line binaries
+  --enable-fsts           enable all FST SOs
   --enable-grm            enable all dependencies of OpenGrm
 
 Optional Packages:
@@ -1598,7 +1602,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.5
+OpenFst configure 1.7.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2039,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.5, which was
+It was created by OpenFst $as_me 1.7.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2902,7 +2906,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.5'
+ VERSION='1.7.6'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4594,7 +4598,7 @@ fi
 
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++11 -fno-exceptions"
+CXX="$CXX -std=c++17 -fno-exceptions"
 
 # Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then :
@@ -9130,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*)
@@ -16834,7 +16844,26 @@ else
 fi
 
 
-# --enable-grm enables dependencies of OpenGrm: far, mpdt, and pdt.
+# --enable-fsts is an alias to enable FST SO extensions: compact, const,
+# linear, lookahead, and ngram.
+# Check whether --enable-fsts was given.
+if test "${enable_fsts+set}" = set; then :
+  enableval=$enable_fsts;
+else
+  enable_fsts=no
+fi
+
+ if test "x$enable_fsts" != xno; then
+  HAVE_FSTS_TRUE=
+  HAVE_FSTS_FALSE='#'
+else
+  HAVE_FSTS_TRUE='#'
+  HAVE_FSTS_FALSE=
+fi
+
+
+# --enable-grm is an alias to enable all dependencies of OpenGrm: far, mpdt,
+# and pdt.
 # Check whether --enable-grm was given.
 if test "${enable_grm+set}" = set; then :
   enableval=$enable_grm;
@@ -17150,6 +17179,10 @@ if test -z "${HAVE_SCRIPT_TRUE}" && test -z "${HAVE_SCRIPT_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_SCRIPT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_FSTS_TRUE}" && test -z "${HAVE_FSTS_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_FSTS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${HAVE_GRM_TRUE}" && test -z "${HAVE_GRM_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_GRM\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -17551,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.5, which was
+This file was extended by OpenFst $as_me 1.7.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17617,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.5
+OpenFst config.status 1.7.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index f8777cf..718dd0f 100644 (file)
@@ -1,11 +1,11 @@
-AC_INIT([OpenFst], [1.7.5], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.7.6], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
 AC_PROG_CXX
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++11 -fno-exceptions"
+CXX="$CXX -std=c++17 -fno-exceptions"
 
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
@@ -125,7 +125,17 @@ AC_ARG_ENABLE([bin],
 AM_CONDITIONAL([HAVE_BIN], [test "x$enable_bin" != xno])
 AM_CONDITIONAL([HAVE_SCRIPT], [test "x$enable_bin" != xno])
 
-# --enable-grm enables dependencies of OpenGrm: far, mpdt, and pdt.
+# --enable-fsts is an alias to enable FST SO extensions: compact, const,
+# linear, lookahead, and ngram.
+AC_ARG_ENABLE([fsts],
+              [AS_HELP_STRING([--enable-fsts],
+              [enable all FST SOs])],
+              [],
+              [enable_fsts=no])
+AM_CONDITIONAL([HAVE_FSTS], [test "x$enable_fsts" != xno])
+
+# --enable-grm is an alias to enable all dependencies of OpenGrm: far, mpdt,
+# and pdt.
 AC_ARG_ENABLE([grm],
               [AS_HELP_STRING([--enable-grm],
               [enable all dependencies of OpenGrm])],
index c12c197..d11f1e0 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-9"
+VERSION="2.4.6 Debian-2.4.6-11"
 package_revision=2.4.6
 
 
@@ -2141,7 +2141,7 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-9
+       version:        $progname $scriptversion Debian-2.4.6-11
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
index c81e669..9d6dd9f 100644 (file)
@@ -4704,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*)
index f42e078..2149c70 100644 (file)
@@ -14,6 +14,14 @@ if HAVE_FAR
 fardir = far
 endif
 
+if HAVE_FSTS
+compactdir = compact
+constdir = const
+lineardir = linear
+lookaheaddir = lookahead
+ngramdir = ngram
+endif
+
 if HAVE_GRM
 fardir = far
 pdtdir = pdt
index 6308dcc..2720a15 100644 (file)
@@ -322,19 +322,24 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 @HAVE_COMPACT_TRUE@compactdir = compact
+@HAVE_FSTS_TRUE@compactdir = compact
 @HAVE_COMPRESS_TRUE@compressdir = compress
 @HAVE_CONST_TRUE@constdir = const
+@HAVE_FSTS_TRUE@constdir = const
 @HAVE_FAR_TRUE@fardir = far
 @HAVE_GRM_TRUE@fardir = far
 @HAVE_PYTHON_TRUE@fardir = far
+@HAVE_FSTS_TRUE@lineardir = linear
+@HAVE_LINEAR_TRUE@lineardir = linear
+@HAVE_FSTS_TRUE@lookaheaddir = lookahead
+@HAVE_LOOKAHEAD_TRUE@lookaheaddir = lookahead
+@HAVE_FSTS_TRUE@ngramdir = ngram
+@HAVE_NGRAM_TRUE@ngramdir = ngram
 @HAVE_GRM_TRUE@pdtdir = pdt
 @HAVE_MPDT_TRUE@pdtdir = pdt
 @HAVE_PDT_TRUE@pdtdir = pdt
 @HAVE_GRM_TRUE@mpdtdir = mpdt
 @HAVE_MPDT_TRUE@mpdtdir = mpdt
-@HAVE_LINEAR_TRUE@lineardir = linear
-@HAVE_LOOKAHEAD_TRUE@lookaheaddir = lookahead
-@HAVE_NGRAM_TRUE@ngramdir = ngram
 @HAVE_PYTHON_TRUE@pywrapfstdir = python
 @HAVE_SPECIAL_TRUE@specialdir = special
 SUBDIRS = $(compactdir) $(compressdir) $(constdir) $(fardir) $(lineardir)  \
index 9df6f74..765e310 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 18:0:0
+libfstcompact_la_LDFLAGS = -version-info 19:0:0
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
index 12bf19e..064b9bb 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 18:0:0
+libfstcompact_la_LDFLAGS = -version-info 19: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 012b02f..735f092 100644 (file)
@@ -6,17 +6,17 @@ bin_PROGRAMS = fstcompress
 LDADD = libfstcompressscript.la \
         ../../script/libfstscript.la \
         ../../lib/libfst.la \
-        -lz -lm $(DL_LIBS)
+        -lm $(DL_LIBS)
 
 fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 endif
 
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compressscript.cc
-libfstcompressscript_la_LDFLAGS = -version-info 18:0:0
+libfstcompressscript_la_LDFLAGS = -version-info 19:0:0
 libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
                                  ../../lib/libfst.la \
-                                 -lz -lm $(DL_LIBS)
+                                 -lm $(DL_LIBS)
 endif
 
 if HAVE_SCRIPT
index cb51e6f..4266133 100644 (file)
@@ -366,14 +366,14 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@LDADD = libfstcompressscript.la \
 @HAVE_BIN_TRUE@        ../../script/libfstscript.la \
 @HAVE_BIN_TRUE@        ../../lib/libfst.la \
-@HAVE_BIN_TRUE@        -lz -lm $(DL_LIBS)
+@HAVE_BIN_TRUE@        -lm $(DL_LIBS)
 
 @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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 19:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                                 ../../lib/libfst.la \
-@HAVE_SCRIPT_TRUE@                                 -lz -lm $(DL_LIBS)
+@HAVE_SCRIPT_TRUE@                                 -lm $(DL_LIBS)
 
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstcompressscript.la
 all: all-am
index 82c64e8..7174824 100644 (file)
@@ -9,8 +9,8 @@
 namespace fst {
 namespace script {
 
-bool Compress(const FstClass &fst, const std::string &source, const bool gzip) {
-  CompressInnerArgs iargs(fst, source, gzip);
+bool Compress(const FstClass &fst, const std::string &source) {
+  CompressInnerArgs iargs(fst, source);
   CompressArgs args(iargs);
   Apply<Operation<CompressArgs>>("Compress", fst.ArcType(), &args);
   return args.retval;
@@ -18,9 +18,8 @@ bool Compress(const FstClass &fst, const std::string &source, const bool gzip) {
 
 REGISTER_FST_OPERATION_3ARCS(Compress, CompressArgs);
 
-bool Decompress(const std::string &source, MutableFstClass *fst,
-                const bool gzip) {
-  DecompressInnerArgs iargs(source, fst, gzip);
+bool Decompress(const std::string &source, MutableFstClass *fst) {
+  DecompressInnerArgs iargs(source, fst);
   DecompressArgs args(iargs);
   Apply<Operation<DecompressArgs>>("Decompress", fst->ArcType(), &args);
   return args.retval;
index cb4caf3..4062ebb 100644 (file)
@@ -15,7 +15,6 @@
 
 DECLARE_string(arc_type);
 DECLARE_bool(decode);
-DECLARE_bool(gzip);
 
 int fstcompress_main(int argc, char **argv) {
   namespace s = fst::script;
@@ -41,7 +40,7 @@ int fstcompress_main(int argc, char **argv) {
 
   if (FLAGS_decode) {
     VectorFstClass fst(FLAGS_arc_type);
-    if (!s::Decompress(in_name, &fst, FLAGS_gzip)) {
+    if (!s::Decompress(in_name, &fst)) {
       FSTERROR() << "Decompression failed";
       return 1;
     }
@@ -49,7 +48,7 @@ int fstcompress_main(int argc, char **argv) {
   } else {
     std::unique_ptr<FstClass> ifst(FstClass::Read(in_name));
     if (!ifst) return 1;
-    if (!s::Compress(*ifst, out_name, FLAGS_gzip)) {
+    if (!s::Compress(*ifst, out_name)) {
       FSTERROR() << "Compression failed";
       return 1;
     }
index 20cbfd8..14de7ac 100644 (file)
@@ -5,7 +5,6 @@
 
 DEFINE_string(arc_type, "standard", "Output arc type");
 DEFINE_bool(decode, false, "Decode");
-DEFINE_bool(gzip, false, "Also applies gzip (de)compression");
 
 int fstcompress_main(int argc, char **argv);
 
index 0f96d62..1b5dc95 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 18:0:0
+libfstconst_la_LDFLAGS = -version-info 19:0:0
 
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
index 2acde5d..aeafd1f 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 18:0:0
+libfstconst_la_LDFLAGS = -version-info 19:0:0
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
 const16_fst_la_SOURCES = const16-fst.cc
index 6ea4744..4717ade 100644 (file)
@@ -7,13 +7,13 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 18:0:0
+libfstfar_la_LDFLAGS = -version-info 19: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 18:0:0
+libfstfarscript_la_LDFLAGS = -version-info 19:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
index 681056e..794de41 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 18:0:0
+libfstfar_la_LDFLAGS = -version-info 19: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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 19: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 380f884..dd45058 100644 (file)
@@ -3,8 +3,8 @@
 
 #include <fst/extensions/far/far-class.h>
 
-#include <fst/script/script-impl.h>
 #include <fst/extensions/far/script-impl.h>
+#include <fst/script/script-impl.h>
 
 namespace fst {
 namespace script {
index 07819c8..9e23cb7 100644 (file)
@@ -5,6 +5,7 @@
 // those that can be called with FstClass-type arguments.
 
 #include <fst/extensions/far/farscript.h>
+
 #include <fst/extensions/far/far.h>
 #include <fst/script/script-impl.h>
 
index ff406da..b141d2c 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
+#include <fst/extensions/far/stlist.h>
+
 #include <ios>
 
-#include <fst/extensions/far/stlist.h>
 #include <fstream>
 
 namespace fst {
index 950a680..030f39b 100644 (file)
@@ -1,9 +1,10 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 
-#include <fstream>
 #include <fst/extensions/far/sttable.h>
 
+#include <fstream>
+
 namespace fst {
 
 bool IsSTTable(const std::string &source) {
index 05ed87c..b28b583 100644 (file)
@@ -15,7 +15,7 @@ if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstlinearscript.la
 
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 18:0:0
+libfstlinearscript_la_LDFLAGS = -version-info 19:0:0
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 endif
 
index 961d9d5..c2aa44c 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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 19: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 4a011f8..3796c63 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 18:0:0
+libfstlookahead_la_LDFLAGS = -version-info 19:0:0
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
index 51b7a0e..c675874 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 18:0:0
+libfstlookahead_la_LDFLAGS = -version-info 19: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 88738ce..510441e 100644 (file)
@@ -20,7 +20,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 18:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 19:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 0de3702..8629b5f 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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 19:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
index 99ca7b3..fc27371 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 18:0:0
+libfstngram_la_LDFLAGS = -version-info 19:0:0
index dab5340..092ec1f 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 18:0:0
+libfstngram_la_LDFLAGS = -version-info 19:0:0
 all: all-am
 
 .SUFFIXES:
index 70f7dbf..9998f0a 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 18:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 19:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 05122ba..c87af19 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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 19:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
index 8427bef..974b770 100644 (file)
@@ -1,12 +1,12 @@
-# NB: we use the Cython-generated .cc files rather than the *.pxd/.pyx sources
+# NB: we use the Cython-generated .cpp files rather than the *.pxd/.pyx sources
 # used to generate them. Consequently, modifications to the .pyx files will not
-# influence the build unless the .cc files are regenerated using Cython.
+# influence the build unless the .cpp files are regenerated using Cython.
 
 python_LTLIBRARIES = pywrapfst.la
 
 pyexec_LTILIBRARIES = pywrapfst.la
 
-pywrapfst_la_SOURCES = pywrapfst.cc
+pywrapfst_la_SOURCES = pywrapfst.cpp
 pywrapfst_la_CPPFLAGS = -I$(srcdir)/../../include $(PYTHON_CPPFLAGS)
 pywrapfst_la_CXXFLAGS = -fexceptions
 pywrapfst_la_LDFLAGS = -avoid-version -module
@@ -15,4 +15,5 @@ pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
                       -lm $(DL_LIBS) $(PYTHON_LIBS)
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd pywrapfst.pxd pywrapfst.pyx
+EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd \
+             pywrapfst.pxd pywrapfst.pyx utility.pxd
index 824f36c..765333e 100644 (file)
@@ -14,9 +14,9 @@
 
 @SET_MAKE@
 
-# NB: we use the Cython-generated .cc files rather than the *.pxd/.pyx sources
+# NB: we use the Cython-generated .cpp files rather than the *.pxd/.pyx sources
 # used to generate them. Consequently, modifications to the .pyx files will not
-# influence the build unless the .cc files are regenerated using Cython.
+# influence the build unless the .cpp files are regenerated using Cython.
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
@@ -351,7 +351,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 python_LTLIBRARIES = pywrapfst.la
 pyexec_LTILIBRARIES = pywrapfst.la
-pywrapfst_la_SOURCES = pywrapfst.cc
+pywrapfst_la_SOURCES = pywrapfst.cpp
 pywrapfst_la_CPPFLAGS = -I$(srcdir)/../../include $(PYTHON_CPPFLAGS)
 pywrapfst_la_CXXFLAGS = -fexceptions
 pywrapfst_la_LDFLAGS = -avoid-version -module
@@ -361,11 +361,13 @@ pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
 
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd pywrapfst.pxd pywrapfst.pyx
+EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd \
+             pywrapfst.pxd pywrapfst.pyx utility.pxd
+
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .cpp .lo .o .obj
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
@@ -448,7 +450,7 @@ $(am__depfiles_remade):
 
 am--depfiles: $(am__depfiles_remade)
 
-.cc.o:
+.cpp.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
 @am__fastdepCXX_TRUE@  $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
 @am__fastdepCXX_TRUE@  $(am__mv) $$depbase.Tpo $$depbase.Po
@@ -456,7 +458,7 @@ am--depfiles: $(am__depfiles_remade)
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
 
-.cc.obj:
+.cpp.obj:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
 @am__fastdepCXX_TRUE@  $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
 @am__fastdepCXX_TRUE@  $(am__mv) $$depbase.Tpo $$depbase.Po
@@ -464,7 +466,7 @@ am--depfiles: $(am__depfiles_remade)
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-.cc.lo:
+.cpp.lo:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
 @am__fastdepCXX_TRUE@  $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
 @am__fastdepCXX_TRUE@  $(am__mv) $$depbase.Tpo $$depbase.Plo
@@ -472,12 +474,12 @@ am--depfiles: $(am__depfiles_remade)
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
-pywrapfst_la-pywrapfst.lo: pywrapfst.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -MT pywrapfst_la-pywrapfst.lo -MD -MP -MF $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
+pywrapfst_la-pywrapfst.lo: pywrapfst.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -MT pywrapfst_la-pywrapfst.lo -MD -MP -MF $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cpp' || echo '$(srcdir)/'`pywrapfst.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/pywrapfst_la-pywrapfst.Tpo $(DEPDIR)/pywrapfst_la-pywrapfst.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='pywrapfst.cc' object='pywrapfst_la-pywrapfst.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='pywrapfst.cpp' object='pywrapfst_la-pywrapfst.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cc' || echo '$(srcdir)/'`pywrapfst.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pywrapfst_la_CPPFLAGS) $(CPPFLAGS) $(pywrapfst_la_CXXFLAGS) $(CXXFLAGS) -c -o pywrapfst_la-pywrapfst.lo `test -f 'pywrapfst.cpp' || echo '$(srcdir)/'`pywrapfst.cpp
 
 mostlyclean-libtool:
        -rm -f *.lo
index fb80e4e..69f88d0 100644 (file)
@@ -166,6 +166,28 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
     SymbolTableTextOptions(bool)
 
+  # This is actually a nested class, but Cython doesn't need to know that.
+  cdef cppclass SymbolTableIterator "fst::SymbolTable::iterator":
+
+      SymbolTableIterator(const SymbolTableIterator &)
+
+      cppclass value_type:
+
+        int64 Label()
+        string Symbol()
+
+      # When wrapped in a unique_ptr siter.Label() and siter.Symbol() are
+      # ambiguous to Cython because there's no way to make the -> explicit.
+      # This hacks around that.
+      const value_type &Pair "operator*"()
+
+      SymbolTableIterator &operator++()
+
+      bool operator==(const SymbolTableIterator &, const SymbolTableIterator &)
+
+      bool operator!=(const SymbolTableIterator &, const SymbolTableIterator &)
+
+
   # Symbol tables.
   cdef cppclass SymbolTable:
 
@@ -224,6 +246,10 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
     bool WriteText(const string &)
 
+    SymbolTableIterator begin()
+
+    SymbolTableIterator end()
+
     int64 AvailableKey()
 
     size_t NumSymbols()
@@ -235,20 +261,6 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
   SymbolTable *FstReadSymbols(const string &, bool)
 
-  cdef cppclass SymbolTableIterator:
-
-    SymbolTableIterator(const SymbolTable &)
-
-    bool Done()
-
-    void Next()
-
-    void Reset()
-
-    string Symbol()
-
-    int64 Value()
-
 
 cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
@@ -369,9 +381,9 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
     bool SetFinal(int64, const WeightClass &)
 
-    void SetInputSymbols(SymbolTable *)
+    void SetInputSymbols(const SymbolTable *)
 
-    void SetOutputSymbols(SymbolTable *)
+    void SetOutputSymbols(const SymbolTable *)
 
     void SetProperties(uint64, uint64)
 
similarity index 80%
rename from src/extensions/python/pywrapfst.cc
rename to src/extensions/python/pywrapfst.cpp
index c91b462..9f08b01 100644 (file)
@@ -1,4 +1,33 @@
-/* Generated by Cython 0.29.13 */
+/* 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 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -7,8 +36,8 @@
 #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_13"
-#define CYTHON_HEX_VERSION 0x001D0DF0
+#define CYTHON_ABI "0_29_15"
+#define CYTHON_HEX_VERSION 0x001D0FF0
 #define CYTHON_FUTURE_DIVISION 1
 #include <stddef.h>
 #ifndef offsetof
@@ -619,6 +648,7 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include <utility>
 #include <vector>
 #include <stdint.h>
+#include <fst/types.h>
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -631,6 +661,25 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include <fst/extensions/far/far-class.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <fst/compat.h>
+
+    #include <type_traits>
+    #include <utility>
+
+    namespace fst {
+
+    template <typename T>
+    inline typename std::remove_reference<T>::type &&move(T &t) {
+        return std::move(t);
+    }
+
+    template <typename T>
+    inline typename std::remove_reference<T>::type &&move(T &&t) {
+        return std::move(t);
+    }
+
+    }  // namespace fst
+    
 #ifdef _OPENMP
 #include <omp.h>
 #endif /* _OPENMP */
@@ -839,91 +888,23 @@ static const char *__pyx_filename;
 
 
 static const char *__pyx_f[] = {
-  "pywrapfst.pyx",
+  "src/pywrapfst.pyx",
   "stringsource",
 };
 
-/* "basictypes.pxd":22
- * 
- * 
- * ctypedef int8_t int8             # <<<<<<<<<<<<<<
- * ctypedef int16_t int16
- * ctypedef int32_t int32
- */
-typedef int8_t __pyx_t_10basictypes_int8;
-
-/* "basictypes.pxd":23
- * 
- * ctypedef int8_t int8
- * ctypedef int16_t int16             # <<<<<<<<<<<<<<
- * ctypedef int32_t int32
- * ctypedef int64_t int64
- */
-typedef int16_t __pyx_t_10basictypes_int16;
-
-/* "basictypes.pxd":24
- * ctypedef int8_t int8
- * ctypedef int16_t int16
- * ctypedef int32_t int32             # <<<<<<<<<<<<<<
- * ctypedef int64_t int64
- * ctypedef uint8_t uint8
- */
-typedef int32_t __pyx_t_10basictypes_int32;
-
-/* "basictypes.pxd":25
- * ctypedef int16_t int16
- * ctypedef int32_t int32
- * ctypedef int64_t int64             # <<<<<<<<<<<<<<
- * ctypedef uint8_t uint8
- * ctypedef uint16_t uint16
- */
-typedef int64_t __pyx_t_10basictypes_int64;
-
-/* "basictypes.pxd":26
- * ctypedef int32_t int32
- * ctypedef int64_t int64
- * ctypedef uint8_t uint8             # <<<<<<<<<<<<<<
- * ctypedef uint16_t uint16
- * ctypedef uint32_t uint32
- */
-typedef uint8_t __pyx_t_10basictypes_uint8;
-
-/* "basictypes.pxd":27
- * ctypedef int64_t int64
- * ctypedef uint8_t uint8
- * ctypedef uint16_t uint16             # <<<<<<<<<<<<<<
- * ctypedef uint32_t uint32
- * ctypedef uint64_t uint64
- */
-typedef uint16_t __pyx_t_10basictypes_uint16;
-
-/* "basictypes.pxd":28
- * ctypedef uint8_t uint8
- * ctypedef uint16_t uint16
- * ctypedef uint32_t uint32             # <<<<<<<<<<<<<<
- * ctypedef uint64_t uint64
- */
-typedef uint32_t __pyx_t_10basictypes_uint32;
-
-/* "basictypes.pxd":29
- * ctypedef uint16_t uint16
- * ctypedef uint32_t uint32
- * ctypedef uint64_t uint64             # <<<<<<<<<<<<<<
- */
-typedef uint64_t __pyx_t_10basictypes_uint64;
-
 /*--- Type declarations ---*/
 struct __pyx_obj_9pywrapfst_Weight;
 struct __pyx_obj_9pywrapfst__SymbolTable;
-struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable;
-struct __pyx_obj_9pywrapfst__FstSymbolTable;
+struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView;
+struct __pyx_obj_9pywrapfst__FstSymbolTableView;
 struct __pyx_obj_9pywrapfst__MutableSymbolTable;
-struct __pyx_obj_9pywrapfst__MutableFstSymbolTable;
+struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView;
 struct __pyx_obj_9pywrapfst_SymbolTable;
-struct __pyx_obj_9pywrapfst_SymbolTableIterator;
+struct __pyx_obj_9pywrapfst__SymbolTableIterator;
 struct __pyx_obj_9pywrapfst_EncodeMapper;
-struct __pyx_obj_9pywrapfst__Fst;
-struct __pyx_obj_9pywrapfst__MutableFst;
+struct __pyx_obj_9pywrapfst_Fst;
+struct __pyx_obj_9pywrapfst_MutableFst;
+struct __pyx_obj_9pywrapfst_VectorFst;
 struct __pyx_obj_9pywrapfst_Arc;
 struct __pyx_obj_9pywrapfst_ArcIterator;
 struct __pyx_obj_9pywrapfst_MutableArcIterator;
@@ -933,40 +914,40 @@ struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
 
-/* "fst.pxd":488
+/* "cpywrapfst.pxd":500
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
  * 
  * ctypedef pair[int64, int64] LabelPair
  */
-typedef std::pair<__pyx_t_10basictypes_int64,fst::script::FstClass const *>  __pyx_t_3fst_LabelFstClassPair;
+typedef std::pair<int64,fst::script::FstClass const *>  __pyx_t_10cpywrapfst_LabelFstClassPair;
 
-/* "fst.pxd":490
+/* "cpywrapfst.pxd":502
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
  * 
  * 
  */
-typedef std::pair<__pyx_t_10basictypes_int64,__pyx_t_10basictypes_int64>  __pyx_t_3fst_LabelPair;
+typedef std::pair<int64,int64>  __pyx_t_10cpywrapfst_LabelPair;
 struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol;
-struct __pyx_opt_args_9pywrapfst_4_Fst_draw;
-struct __pyx_opt_args_9pywrapfst_4_Fst_text;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__project;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__push;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon;
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final;
-struct __pyx_opt_args_9pywrapfst__create_Fst;
+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;
+struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables;
+struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight;
+struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon;
+struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final;
 struct __pyx_opt_args_9pywrapfst__map;
 struct __pyx_opt_args_9pywrapfst_arcmap;
 struct __pyx_opt_args_9pywrapfst_compose;
@@ -992,24 +973,42 @@ struct __pyx_opt_args_9pywrapfst_shortestpath;
  * # SymbolTable.
  * 
  * ctypedef fst.SymbolTable * SymbolTable_ptr             # <<<<<<<<<<<<<<
- * 
+ * ctypedef const fst.SymbolTable * const_SymbolTable_ptr
  * 
  */
 typedef fst::SymbolTable *__pyx_t_9pywrapfst_SymbolTable_ptr;
 
-/* "pywrapfst.pxd":145
- * cdef class _MutableSymbolTable(_SymbolTable):
+/* "pywrapfst.pxd":104
+ * 
+ * ctypedef fst.SymbolTable * SymbolTable_ptr
+ * ctypedef const fst.SymbolTable * const_SymbolTable_ptr             # <<<<<<<<<<<<<<
  * 
- *   cpdef int64 add_symbol(self, symbol, int64 key=?)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void add_table(self, _SymbolTable syms)
+ */
+typedef fst::SymbolTable const *__pyx_t_9pywrapfst_const_SymbolTable_ptr;
+
+/* "pywrapfst.pxd":160
+ *   cdef fst.SymbolTable *_mutable_raw_ptr_or_raise(self) except *
+ * 
+ *   cpdef int64 add_symbol(self, symbol, int64 key=?) except *             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef void add_table(self, _SymbolTable syms) except *
  */
 struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
   int __pyx_n;
-  __pyx_t_10basictypes_int64 key;
+  int64 key;
 };
 
-/* "pywrapfst.pxd":233
+/* "pywrapfst.pxd":207
+ * 
+ * 
+ * ctypedef fst.EncodeMapperClass * EncodeMapperClass_ptr             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+typedef fst::script::EncodeMapperClass *__pyx_t_9pywrapfst_EncodeMapperClass_ptr;
+
+/* "pywrapfst.pxd":243
  * 
  * 
  * ctypedef fst.FstClass * FstClass_ptr             # <<<<<<<<<<<<<<
@@ -1018,7 +1017,7 @@ struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
  */
 typedef fst::script::FstClass *__pyx_t_9pywrapfst_FstClass_ptr;
 
-/* "pywrapfst.pxd":234
+/* "pywrapfst.pxd":244
  * 
  * ctypedef fst.FstClass * FstClass_ptr
  * ctypedef const fst.FstClass * const_FstClass_ptr             # <<<<<<<<<<<<<<
@@ -1027,7 +1026,7 @@ typedef fst::script::FstClass *__pyx_t_9pywrapfst_FstClass_ptr;
  */
 typedef fst::script::FstClass const *__pyx_t_9pywrapfst_const_FstClass_ptr;
 
-/* "pywrapfst.pxd":235
+/* "pywrapfst.pxd":245
  * ctypedef fst.FstClass * FstClass_ptr
  * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr             # <<<<<<<<<<<<<<
@@ -1036,7 +1035,7 @@ typedef fst::script::FstClass const *__pyx_t_9pywrapfst_const_FstClass_ptr;
  */
 typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
 
-/* "pywrapfst.pxd":236
+/* "pywrapfst.pxd":246
  * ctypedef const fst.FstClass * const_FstClass_ptr
  * ctypedef fst.MutableFstClass * MutableFstClass_ptr
  * ctypedef fst.VectorFstClass * VectorFstClass_ptr             # <<<<<<<<<<<<<<
@@ -1045,14 +1044,14 @@ typedef fst::script::MutableFstClass *__pyx_t_9pywrapfst_MutableFstClass_ptr;
  */
 typedef fst::script::VectorFstClass *__pyx_t_9pywrapfst_VectorFstClass_ptr;
 
-/* "pywrapfst.pxd":252
- *   cpdef _Fst copy(self)
+/* "pywrapfst.pxd":262
+ *   cpdef Fst copy(self)
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
  *                   _SymbolTable isymbols=?,
  */
-struct __pyx_opt_args_9pywrapfst_4_Fst_draw {
+struct __pyx_opt_args_9pywrapfst_3Fst_draw {
   int __pyx_n;
   struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
   struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
@@ -1065,20 +1064,37 @@ struct __pyx_opt_args_9pywrapfst_4_Fst_draw {
   bool vertical;
   double ranksep;
   double nodesep;
-  __pyx_t_10basictypes_int32 fontsize;
-  __pyx_t_10basictypes_int32 precision;
+  int32 fontsize;
+  int32 precision;
   PyObject *float_format;
   bool show_weight_one;
 };
 
-/* "pywrapfst.pxd":290
+/* "pywrapfst.pxd":294
+ *   cpdef _FstSymbolTableView output_symbols(self)
+ * 
+ *   cpdef string print(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=?,
+ *                     _SymbolTable 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;
+  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_4_Fst_text {
+struct __pyx_opt_args_9pywrapfst_3Fst_text {
   int __pyx_n;
   struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
   struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
@@ -1088,128 +1104,128 @@ struct __pyx_opt_args_9pywrapfst_4_Fst_text {
   PyObject *missing_sym;
 };
 
-/* "pywrapfst.pxd":319
- *   cpdef void add_states(self, size_t) except *
+/* "pywrapfst.pxd":337
+ *   cpdef void add_states(self, size_t)
  * 
  *   cdef void _arcsort(self, sort_type=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cdef void _closure(self, bool closure_plus=?) except *
+ *   cdef void _closure(self, bool closure_plus=?)
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort {
   int __pyx_n;
   PyObject *sort_type;
 };
 
-/* "pywrapfst.pxd":321
+/* "pywrapfst.pxd":339
  *   cdef void _arcsort(self, sort_type=?) except *
  * 
- *   cdef void _closure(self, bool closure_plus=?) except *             # <<<<<<<<<<<<<<
+ *   cdef void _closure(self, bool closure_plus=?)             # <<<<<<<<<<<<<<
  * 
- *   cdef void _concat(self, _Fst fst2) except *
+ *   cdef void _concat(self, Fst fst2) except *
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__closure {
   int __pyx_n;
   bool closure_plus;
 };
 
-/* "pywrapfst.pxd":329
+/* "pywrapfst.pxd":347
  *   cdef void _decode(self, EncodeMapper) except *
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _delete_states(self, states=?) except *
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs {
   int __pyx_n;
   size_t n;
 };
 
-/* "pywrapfst.pxd":331
+/* "pywrapfst.pxd":349
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *
  * 
  *   cdef void _delete_states(self, states=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _encode(self, EncodeMapper) except *
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states {
   int __pyx_n;
   PyObject *states;
 };
 
-/* "pywrapfst.pxd":337
- *   cdef void _invert(self) except *
+/* "pywrapfst.pxd":355
+ *   cdef void _invert(self)
  * 
  *   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state)
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize {
   int __pyx_n;
   float delta;
   bool allow_nondet;
 };
 
-/* "pywrapfst.pxd":343
+/* "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_11_MutableFst__project {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__project {
   int __pyx_n;
   bool project_output;
 };
 
-/* "pywrapfst.pxd":345
+/* "pywrapfst.pxd":363
  *   cdef void _project(self, bool project_output=?) except *
  * 
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _push(self,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__prune {
   int __pyx_n;
   float delta;
-  __pyx_t_10basictypes_int64 nstate;
+  int64 nstate;
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":347
+/* "pywrapfst.pxd":365
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
  *                   float delta=?,
  *                   bool remove_total_weight=?,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__push {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__push {
   int __pyx_n;
   float delta;
   bool remove_total_weight;
   bool to_final;
 };
 
-/* "pywrapfst.pxd":352
- *                   bool to_final=?) except *
+/* "pywrapfst.pxd":370
+ *                   bool to_final=?)
  * 
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _relabel_tables(self,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs {
   int __pyx_n;
   PyObject *ipairs;
   PyObject *opairs;
 };
 
-/* "pywrapfst.pxd":354
+/* "pywrapfst.pxd":372
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
  *                             _SymbolTable old_isymbols=?,
  *                             _SymbolTable new_isymbols=?,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables {
+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;
@@ -1221,64 +1237,52 @@ struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables {
   bool attach_new_osymbols;
 };
 
-/* "pywrapfst.pxd":368
- *   cdef void _reserve_states(self, int64 n) except *
+/* "pywrapfst.pxd":386
+ *   cdef void _reserve_states(self, int64 n)
  * 
  *   cdef void _reweight(self, potentials, bool to_final=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _rmepsilon(self,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight {
   int __pyx_n;
   bool to_final;
 };
 
-/* "pywrapfst.pxd":370
+/* "pywrapfst.pxd":388
  *   cdef void _reweight(self, potentials, bool to_final=?) except *
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
  *                        queue_type=?,
  *                        bool connect=?,
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon {
   int __pyx_n;
   PyObject *queue_type;
   bool connect;
   PyObject *weight;
-  __pyx_t_10basictypes_int64 nstate;
+  int64 nstate;
   float delta;
 };
 
-/* "pywrapfst.pxd":377
+/* "pywrapfst.pxd":395
  *                        float delta=?) except *
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask)
  */
-struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final {
+struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final {
   int __pyx_n;
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":399
- * cdef _Fst _init_XFst(FstClass_ptr tfst)
- * 
- * cdef _MutableFst _create_Fst(arc_type=?)             # <<<<<<<<<<<<<<
- * 
- * cpdef _Fst _read(source)
- */
-struct __pyx_opt_args_9pywrapfst__create_Fst {
-  int __pyx_n;
-  PyObject *arc_type;
-};
-
-/* "pywrapfst.pxd":482
+/* "pywrapfst.pxd":503
  * 
  * 
- * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
+ * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _Fst arcmap(_Fst ifst,
+ * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  */
 struct __pyx_opt_args_9pywrapfst__map {
   int __pyx_n;
@@ -1288,12 +1292,12 @@ struct __pyx_opt_args_9pywrapfst__map {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":484
- * cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
+/* "pywrapfst.pxd":505
+ * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
- * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
- *                   float delta=?,
- *                   map_type=?,
+ * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
+ * 
+ * cpdef MutableFst compose(Fst ifst1,
  */
 struct __pyx_opt_args_9pywrapfst_arcmap {
   int __pyx_n;
@@ -1303,12 +1307,12 @@ struct __pyx_opt_args_9pywrapfst_arcmap {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":490
- *                   weight=?)
+/* "pywrapfst.pxd":507
+ * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
- * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
- *                           compose_filter=?,
+ * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                          Fst ifst2,
+ *                          compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_compose {
   int __pyx_n;
@@ -1316,41 +1320,41 @@ struct __pyx_opt_args_9pywrapfst_compose {
   bool connect;
 };
 
-/* "pywrapfst.pxd":495
- *                           bool connect=?)
+/* "pywrapfst.pxd":512
+ *                          bool connect=?)
  * 
- * cpdef _Fst convert(_Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
+ * cpdef Fst convert(Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst determinize(_Fst ifst,
+ * cpdef MutableFst determinize(Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_convert {
   int __pyx_n;
   PyObject *fst_type;
 };
 
-/* "pywrapfst.pxd":497
- * cpdef _Fst convert(_Fst ifst, fst_type=?)
+/* "pywrapfst.pxd":514
+ * cpdef Fst convert(Fst ifst, fst_type=?)
  * 
- * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
- *                               float delta=?,
- *                               det_type=?,
+ * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
+ *                              float delta=?,
+ *                              det_type=?,
  */
 struct __pyx_opt_args_9pywrapfst_determinize {
   int __pyx_n;
   float delta;
   PyObject *det_type;
-  __pyx_t_10basictypes_int64 nstate;
-  __pyx_t_10basictypes_int64 subsequential_label;
+  int64 nstate;
+  int64 subsequential_label;
   PyObject *weight;
   bool increment_subsequential_label;
 };
 
-/* "pywrapfst.pxd":505
- *                               bool increment_subsequential_label=?)
+/* "pywrapfst.pxd":522
+ *                              bool increment_subsequential_label=?)
  * 
- * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                              _Fst ifst2,
- *                              compose_filter=?,
+ * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                             Fst ifst2,
+ *                             compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_difference {
   int __pyx_n;
@@ -1358,63 +1362,63 @@ struct __pyx_opt_args_9pywrapfst_difference {
   bool connect;
 };
 
-/* "pywrapfst.pxd":510
- *                              bool connect=?)
+/* "pywrapfst.pxd":527
+ *                             bool connect=?)
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=?,
- *                                int64 nstate=?,
+ * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=?,
+ *                               int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst_disambiguate {
   int __pyx_n;
   float delta;
-  __pyx_t_10basictypes_int64 nstate;
-  __pyx_t_10basictypes_int64 subsequential_label;
+  int64 nstate;
+  int64 subsequential_label;
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":516
- *                                weight=?)
+/* "pywrapfst.pxd":533
+ *                               weight=?)
  * 
- * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
+ * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)
  */
 struct __pyx_opt_args_9pywrapfst_epsnormalize {
   int __pyx_n;
   bool eps_norm_output;
 };
 
-/* "pywrapfst.pxd":518
- * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)
+/* "pywrapfst.pxd":535
+ * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)
  * 
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *
  */
 struct __pyx_opt_args_9pywrapfst_equal {
   int __pyx_n;
   float delta;
 };
 
-/* "pywrapfst.pxd":520
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
+/* "pywrapfst.pxd":537
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)
  * 
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst intersect(_Fst ifst1,
+ * cpdef MutableFst intersect(Fst ifst1,
  */
 struct __pyx_opt_args_9pywrapfst_equivalent {
   int __pyx_n;
   float delta;
 };
 
-/* "pywrapfst.pxd":522
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
+/* "pywrapfst.pxd":539
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *
  * 
- * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                             _Fst ifst2,
- *                             compose_filter=?,
+ * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                            Fst ifst2,
+ *                            compose_filter=?,
  */
 struct __pyx_opt_args_9pywrapfst_intersect {
   int __pyx_n;
@@ -1422,38 +1426,38 @@ struct __pyx_opt_args_9pywrapfst_intersect {
   bool connect;
 };
 
-/* "pywrapfst.pxd":527
- *                             bool connect=?)
+/* "pywrapfst.pxd":544
+ *                            bool connect=?)
  * 
- * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
+ * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
  * 
- * cpdef _MutableFst prune(_Fst ifst,
+ * cpdef MutableFst prune(Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_isomorphic {
   int __pyx_n;
   float delta;
 };
 
-/* "pywrapfst.pxd":529
- * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)
+/* "pywrapfst.pxd":546
+ * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)
  * 
- * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
- *                         float delta=?,
- *                         int64 nstate=?,
+ * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
+ *                        float delta=?,
+ *                        int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst_prune {
   int __pyx_n;
   float delta;
-  __pyx_t_10basictypes_int64 nstate;
+  int64 nstate;
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":534
- *                         weight=?)
+/* "pywrapfst.pxd":551
+ *                        weight=?)
  * 
- * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
- *                        float delta=?,
- *                        bool push_weights=?,
+ * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
+ *                       float delta=?,
+ *                       bool push_weights=?,
  */
 struct __pyx_opt_args_9pywrapfst_push {
   int __pyx_n;
@@ -1465,93 +1469,93 @@ struct __pyx_opt_args_9pywrapfst_push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":542
- *                        bool to_final=?)
+/* "pywrapfst.pxd":559
+ *                       bool to_final=?)
  * 
- * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
+ * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                           Fst ifst2,
  *                           int32 npath=?,
  */
 struct __pyx_opt_args_9pywrapfst_randequivalent {
   int __pyx_n;
-  __pyx_t_10basictypes_int32 npath;
+  int32 npath;
   float delta;
   time_t seed;
   PyObject *select;
-  __pyx_t_10basictypes_int32 max_length;
+  int32 max_length;
 };
 
-/* "pywrapfst.pxd":550
+/* "pywrapfst.pxd":567
  *                           int32 max_length=?) except *
  * 
- * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
- *                           int32 npath=?,
- *                           time_t seed=?,
+ * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
+ *                          int32 npath=?,
+ *                          time_t seed=?,
  */
 struct __pyx_opt_args_9pywrapfst_randgen {
   int __pyx_n;
-  __pyx_t_10basictypes_int32 npath;
+  int32 npath;
   time_t seed;
   PyObject *select;
-  __pyx_t_10basictypes_int32 max_length;
+  int32 max_length;
   bool remove_total_weight;
   bool weighted;
 };
 
-/* "pywrapfst.pxd":562
- *     bool epsilon_on_replace) except *
+/* "pywrapfst.pxd":575
+ *                          bool weighted=?)
  * 
- * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                           call_arc_labeling=?,
- *                           return_arc_labeling=?,
+ * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
+ *                          call_arc_labeling=?,
+ *                          return_arc_labeling=?,
  */
 struct __pyx_opt_args_9pywrapfst_replace {
   int __pyx_n;
   PyObject *call_arc_labeling;
   PyObject *return_arc_labeling;
   bool epsilon_on_replace;
-  __pyx_t_10basictypes_int64 return_label;
+  int64 return_label;
 };
 
-/* "pywrapfst.pxd":568
- *                           int64 return_label=?)
+/* "pywrapfst.pxd":581
+ *                          int64 return_label=?)
  * 
- * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
+ * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+ * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_reverse {
   int __pyx_n;
   bool require_superinitial;
 };
 
-/* "pywrapfst.pxd":570
- * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)
+/* "pywrapfst.pxd":583
+ * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                                                 float delta=?,
  *                                                 int64 nstate=?,
  */
 struct __pyx_opt_args_9pywrapfst__shortestdistance {
   int __pyx_n;
   float delta;
-  __pyx_t_10basictypes_int64 nstate;
+  int64 nstate;
   PyObject *queue_type;
   bool reverse;
 };
 
-/* "pywrapfst.pxd":576
+/* "pywrapfst.pxd":589
  *                                                 bool reverse=?) except *
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=?,
- *                                int32 nshortest=?,
+ * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=?,
+ *                               int32 nshortest=?,
  */
 struct __pyx_opt_args_9pywrapfst_shortestpath {
   int __pyx_n;
   float delta;
-  __pyx_t_10basictypes_int32 nshortest;
-  __pyx_t_10basictypes_int64 nstate;
+  int32 nshortest;
+  int64 nstate;
   PyObject *queue_type;
   bool unique;
   PyObject *weight;
@@ -1571,72 +1575,74 @@ struct __pyx_obj_9pywrapfst_Weight {
 };
 
 
-/* "pywrapfst.pxd":106
+/* "pywrapfst.pxd":107
  * 
  * 
  * cdef class _SymbolTable(object):             # <<<<<<<<<<<<<<
  * 
- *   cdef fst.SymbolTable *_table
+ *   cdef const fst.SymbolTable *_raw(self)
  */
 struct __pyx_obj_9pywrapfst__SymbolTable {
   PyObject_HEAD
   struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtab;
-  fst::SymbolTable *_table;
 };
 
 
-/* "pywrapfst.pxd":133
+/* "pywrapfst.pxd":138
  * 
  * 
- * cdef class _EncodeMapperSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _EncodeMapperSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.EncodeMapperClass] _mapper
+ *   # Indicates whether this view is of an input or output SymbolTable
  */
-struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable {
+struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView {
   struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
+  bool _input_side;
   std::shared_ptr<fst::script::EncodeMapperClass>  _mapper;
 };
 
 
-/* "pywrapfst.pxd":138
+/* "pywrapfst.pxd":146
  * 
  * 
- * cdef class _FstSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _FstSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.FstClass] _fst
+ *   # Indicates whether this view is of an input or output SymbolTable
  */
-struct __pyx_obj_9pywrapfst__FstSymbolTable {
+struct __pyx_obj_9pywrapfst__FstSymbolTableView {
   struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
+  bool _input_side;
   std::shared_ptr<fst::script::FstClass>  _fst;
 };
 
 
-/* "pywrapfst.pxd":143
+/* "pywrapfst.pxd":154
  * 
  * 
  * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
- *   cpdef int64 add_symbol(self, symbol, int64 key=?)
+ *   cdef fst.SymbolTable *_mutable_raw(self)
  */
 struct __pyx_obj_9pywrapfst__MutableSymbolTable {
   struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
 };
 
 
-/* "pywrapfst.pxd":152
+/* "pywrapfst.pxd":167
  * 
  * 
- * cdef class _MutableFstSymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _MutableFstSymbolTableView(_MutableSymbolTable):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.MutableFstClass] _mfst
+ *   # Indicates whether this view is of an input or output SymbolTable
  */
-struct __pyx_obj_9pywrapfst__MutableFstSymbolTable {
+struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView {
   struct __pyx_obj_9pywrapfst__MutableSymbolTable __pyx_base;
+  bool _input_side;
   std::shared_ptr<fst::script::MutableFstClass>  _mfst;
 };
 
 
-/* "pywrapfst.pxd":157
+/* "pywrapfst.pxd":175
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1649,22 +1655,21 @@ struct __pyx_obj_9pywrapfst_SymbolTable {
 };
 
 
-/* "pywrapfst.pxd":182
+/* "pywrapfst.pxd":198
  * 
  * 
- * cdef class SymbolTableIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class _SymbolTableIterator(object):             # <<<<<<<<<<<<<<
  * 
- *   cdef shared_ptr[fst.SymbolTable] _table
+ *   cdef _SymbolTable _table
  */
-struct __pyx_obj_9pywrapfst_SymbolTableIterator {
+struct __pyx_obj_9pywrapfst__SymbolTableIterator {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *__pyx_vtab;
-  std::shared_ptr<fst::SymbolTable>  _table;
-  std::unique_ptr<fst::SymbolTableIterator>  _siter;
+  struct __pyx_obj_9pywrapfst__SymbolTable *_table;
+  std::unique_ptr<fst::SymbolTable::iterator>  _siter;
 };
 
 
-/* "pywrapfst.pxd":201
+/* "pywrapfst.pxd":210
  * 
  * 
  * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
@@ -1678,34 +1683,46 @@ struct __pyx_obj_9pywrapfst_EncodeMapper {
 };
 
 
-/* "pywrapfst.pxd":239
+/* "pywrapfst.pxd":249
  * 
  * 
- * cdef class _Fst(object):             # <<<<<<<<<<<<<<
+ * cdef class Fst(object):             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.FstClass] _fst
  */
-struct __pyx_obj_9pywrapfst__Fst {
+struct __pyx_obj_9pywrapfst_Fst {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst__Fst *__pyx_vtab;
+  struct __pyx_vtabstruct_9pywrapfst_Fst *__pyx_vtab;
   std::shared_ptr<fst::script::FstClass>  _fst;
 };
 
 
-/* "pywrapfst.pxd":307
+/* "pywrapfst.pxd":325
  * 
  * 
- * cdef class _MutableFst(_Fst):             # <<<<<<<<<<<<<<
+ * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
  * 
  *   cdef shared_ptr[fst.MutableFstClass] _mfst
  */
-struct __pyx_obj_9pywrapfst__MutableFst {
-  struct __pyx_obj_9pywrapfst__Fst __pyx_base;
+struct __pyx_obj_9pywrapfst_MutableFst {
+  struct __pyx_obj_9pywrapfst_Fst __pyx_base;
   std::shared_ptr<fst::script::MutableFstClass>  _mfst;
 };
 
 
-/* "pywrapfst.pxd":409
+/* "pywrapfst.pxd":408
+ * 
+ * 
+ * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
+ * 
+ *     pass
+ */
+struct __pyx_obj_9pywrapfst_VectorFst {
+  struct __pyx_obj_9pywrapfst_MutableFst __pyx_base;
+};
+
+
+/* "pywrapfst.pxd":430
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -1719,7 +1736,7 @@ struct __pyx_obj_9pywrapfst_Arc {
 };
 
 
-/* "pywrapfst.pxd":419
+/* "pywrapfst.pxd":440
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1734,7 +1751,7 @@ struct __pyx_obj_9pywrapfst_ArcIterator {
 };
 
 
-/* "pywrapfst.pxd":441
+/* "pywrapfst.pxd":462
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1749,7 +1766,7 @@ struct __pyx_obj_9pywrapfst_MutableArcIterator {
 };
 
 
-/* "pywrapfst.pxd":465
+/* "pywrapfst.pxd":486
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -1764,7 +1781,7 @@ struct __pyx_obj_9pywrapfst_StateIterator {
 };
 
 
-/* "pywrapfst.pxd":592
+/* "pywrapfst.pxd":605
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -1788,7 +1805,7 @@ struct __pyx_obj_9pywrapfst_Compiler {
 };
 
 
-/* "pywrapfst.pxd":613
+/* "pywrapfst.pxd":626
  * # FarReader.
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -1802,7 +1819,7 @@ struct __pyx_obj_9pywrapfst_FarReader {
 };
 
 
-/* "pywrapfst.pxd":638
+/* "pywrapfst.pxd":651
  * # FarWriter.
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -1816,9 +1833,9 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 };
 
 
-/* "pywrapfst.pyx":3193
+/* "pywrapfst.pyx":3237
  * 
- *   # Magic method used to get a Pythonic Iterator API out of the C++ API
+ *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
  *     while not self.done():
  *       yield self.value()
@@ -1830,10 +1847,10 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ {
 
 
 
-/* "pywrapfst.pyx":334
+/* "pywrapfst.pyx":339
  * 
  * 
- * cdef class Weight(object):             # <<<<<<<<<<<<<<
+ * cdef class Weight:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
@@ -1848,19 +1865,22 @@ struct __pyx_vtabstruct_9pywrapfst_Weight {
 static struct __pyx_vtabstruct_9pywrapfst_Weight *__pyx_vtabptr_9pywrapfst_Weight;
 
 
-/* "pywrapfst.pyx":664
+/* "pywrapfst.pyx":669
  * 
  * 
- * cdef class _SymbolTable(object):             # <<<<<<<<<<<<<<
+ * cdef class _SymbolTable:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst__SymbolTable {
-  __pyx_t_10basictypes_int64 (*available_key)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
+  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);
-  __pyx_t_10basictypes_int64 (*get_nth_key)(struct __pyx_obj_9pywrapfst__SymbolTable *, Py_ssize_t, 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);
@@ -1872,35 +1892,35 @@ struct __pyx_vtabstruct_9pywrapfst__SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtabptr_9pywrapfst__SymbolTable;
 
 
-/* "pywrapfst.pyx":850
+/* "pywrapfst.pyx":876
  * 
  * 
- * cdef class _EncodeMapperSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _EncodeMapperSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable {
+struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView {
   struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
 };
-static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
 
 
-/* "pywrapfst.pyx":870
+/* "pywrapfst.pyx":900
  * 
  * 
- * cdef class _FstSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _FstSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable {
+struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView {
   struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
 };
-static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *__pyx_vtabptr_9pywrapfst__FstSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
 
 
-/* "pywrapfst.pyx":889
+/* "pywrapfst.pyx":923
  * 
  * 
  * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
@@ -1910,28 +1930,30 @@ static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *__pyx_vtabptr_9pywrap
 
 struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable {
   struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
-  __pyx_t_10basictypes_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);
+  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 (*set_name)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
 
 
-/* "pywrapfst.pyx":941
+/* "pywrapfst.pyx":994
  * 
  * 
- * cdef class _MutableFstSymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _MutableFstSymbolTableView(_MutableSymbolTable):             # <<<<<<<<<<<<<<
  *   """
  *   (No constructor.)
  */
 
-struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable {
+struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView {
   struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable __pyx_base;
 };
-static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
 
 
-/* "pywrapfst.pyx":952
+/* "pywrapfst.pyx":1009
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1945,129 +1967,126 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable *__pyx_vtabptr_9pywrapfst_SymbolTable;
 
 
-/* "pywrapfst.pyx":1139
+/* "pywrapfst.pyx":1235
  * 
  * 
- * cdef class SymbolTableIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class EncodeMapper:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator {
-  bool (*done)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch);
-  void (*next)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch);
-  void (*reset)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch);
-  std::string (*symbol)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_int64 (*value)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
+  std::string (*arc_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  std::string (*weight_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  uint8 (*flags)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
+  uint64 (*properties)(struct __pyx_obj_9pywrapfst_EncodeMapper *, uint64, int __pyx_skip_dispatch);
+  void (*write)(struct __pyx_obj_9pywrapfst_EncodeMapper *, PyObject *, int __pyx_skip_dispatch);
+  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 *);
 };
-static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *__pyx_vtabptr_9pywrapfst_SymbolTableIterator;
+static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
 
 
-/* "pywrapfst.pyx":1221
+/* "pywrapfst.pyx":1501
  * 
  * 
- * cdef class EncodeMapper(object):             # <<<<<<<<<<<<<<
+ * cdef class Fst:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
-  std::string (*arc_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  std::string (*weight_type)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint64 (*properties)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch);
-  void (*write)(struct __pyx_obj_9pywrapfst_EncodeMapper *, PyObject *, int __pyx_skip_dispatch);
-  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(*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 *, int __pyx_skip_dispatch);
-  void (*set_output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst_Fst {
+  std::string (*_local_render_svg)(std::string const &);
+  std::string (*arc_type)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst_ArcIterator *(*arcs)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst_Fst *(*copy)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  void (*draw)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args);
+  struct __pyx_obj_9pywrapfst_Weight *(*final)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  std::string (*fst_type)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*input_symbols)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  size_t (*num_arcs)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  size_t (*num_input_epsilons)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  size_t (*num_output_epsilons)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*output_symbols)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
+  std::string (*print)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args);
+  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);
+  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
 };
-static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
+static struct __pyx_vtabstruct_9pywrapfst_Fst *__pyx_vtabptr_9pywrapfst_Fst;
 
 
-/* "pywrapfst.pyx":1467
+/* "pywrapfst.pyx":1993
  * 
  * 
- * cdef class _Fst(object):             # <<<<<<<<<<<<<<
+ * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst__Fst {
-  std::string (*_local_render_svg)(std::string const &);
-  std::string (*arc_type)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst_ArcIterator *(*arcs)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__Fst *(*copy)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
-  void (*draw)(struct __pyx_obj_9pywrapfst__Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args);
-  struct __pyx_obj_9pywrapfst_Weight *(*final)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  std::string (*fst_type)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *(*input_symbols)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
-  size_t (*num_arcs)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  size_t (*num_input_epsilons)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  size_t (*num_output_epsilons)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *(*output_symbols)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint64 (*properties)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_uint64, bool, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_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_4_Fst_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);
-  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst_MutableFst {
+  struct __pyx_vtabstruct_9pywrapfst_Fst __pyx_base;
+  void (*_check_mutating_imethod)(struct __pyx_obj_9pywrapfst_MutableFst *);
+  void (*_add_arc)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_obj_9pywrapfst_Arc *);
+  int64 (*add_state)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch);
+  void (*add_states)(struct __pyx_obj_9pywrapfst_MutableFst *, size_t, int __pyx_skip_dispatch);
+  void (*_arcsort)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort *__pyx_optional_args);
+  void (*_closure)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__closure *__pyx_optional_args);
+  void (*_concat)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_Fst *);
+  void (*_connect)(struct __pyx_obj_9pywrapfst_MutableFst *);
+  void (*_decode)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *);
+  void (*_delete_arcs)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs *__pyx_optional_args);
+  void (*_delete_states)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states *__pyx_optional_args);
+  void (*_encode)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *);
+  void (*_invert)(struct __pyx_obj_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 (*_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);
+  void (*_relabel_tables)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables *__pyx_optional_args);
+  void (*_reserve_arcs)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, size_t);
+  void (*_reserve_states)(struct __pyx_obj_9pywrapfst_MutableFst *, int64);
+  void (*_reweight)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *, struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight *__pyx_optional_args);
+  void (*_rmepsilon)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon *__pyx_optional_args);
+  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 (*_topsort)(struct __pyx_obj_9pywrapfst_MutableFst *);
 };
-static struct __pyx_vtabstruct_9pywrapfst__Fst *__pyx_vtabptr_9pywrapfst__Fst;
+static struct __pyx_vtabstruct_9pywrapfst_MutableFst *__pyx_vtabptr_9pywrapfst_MutableFst;
 
 
-/* "pywrapfst.pyx":1888
- * 
+/* "pywrapfst.pyx":2863
  * 
- * cdef class _MutableFst(_Fst):             # <<<<<<<<<<<<<<
  * 
+ * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
  *   """
+ *   VectorFst(arc_type="standard")
  */
 
-struct __pyx_vtabstruct_9pywrapfst__MutableFst {
-  struct __pyx_vtabstruct_9pywrapfst__Fst __pyx_base;
-  void (*_check_mutating_imethod)(struct __pyx_obj_9pywrapfst__MutableFst *);
-  void (*_add_arc)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_obj_9pywrapfst_Arc *);
-  __pyx_t_10basictypes_int64 (*add_state)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch);
-  void (*add_states)(struct __pyx_obj_9pywrapfst__MutableFst *, size_t, int __pyx_skip_dispatch);
-  void (*_arcsort)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args);
-  void (*_closure)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args);
-  void (*_concat)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *);
-  void (*_connect)(struct __pyx_obj_9pywrapfst__MutableFst *);
-  void (*_decode)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *);
-  void (*_delete_arcs)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs *__pyx_optional_args);
-  void (*_delete_states)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states *__pyx_optional_args);
-  void (*_encode)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *);
-  void (*_invert)(struct __pyx_obj_9pywrapfst__MutableFst *);
-  void (*_minimize)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize *__pyx_optional_args);
-  struct __pyx_obj_9pywrapfst_MutableArcIterator *(*mutable_arcs)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_int64 (*num_states)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch);
-  void (*_project)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__project *__pyx_optional_args);
-  void (*_prune)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune *__pyx_optional_args);
-  void (*_push)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__push *__pyx_optional_args);
-  void (*_relabel_pairs)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs *__pyx_optional_args);
-  void (*_relabel_tables)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables *__pyx_optional_args);
-  void (*_reserve_arcs)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, size_t);
-  void (*_reserve_states)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64);
-  void (*_reweight)(struct __pyx_obj_9pywrapfst__MutableFst *, PyObject *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight *__pyx_optional_args);
-  void (*_rmepsilon)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args);
-  void (*_set_final)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final *__pyx_optional_args);
-  void (*_set_properties)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_uint64, __pyx_t_10basictypes_uint64);
-  void (*_set_start)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_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 (*_topsort)(struct __pyx_obj_9pywrapfst__MutableFst *);
+struct __pyx_vtabstruct_9pywrapfst_VectorFst {
+  struct __pyx_vtabstruct_9pywrapfst_MutableFst __pyx_base;
 };
-static struct __pyx_vtabstruct_9pywrapfst__MutableFst *__pyx_vtabptr_9pywrapfst__MutableFst;
+static struct __pyx_vtabstruct_9pywrapfst_VectorFst *__pyx_vtabptr_9pywrapfst_VectorFst;
 
 
-/* "pywrapfst.pyx":2995
+/* "pywrapfst.pyx":3039
  * 
  * 
- * cdef class Arc(object):             # <<<<<<<<<<<<<<
+ * cdef class Arc:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
@@ -2078,53 +2097,53 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":3062
+/* "pywrapfst.pyx":3106
  * 
  * 
- * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class ArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
   bool (*done)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
+  uint8 (*flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   size_t (*position)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
   void (*seek)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst_ArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
   PyObject *(*value)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
 
 
-/* "pywrapfst.pyx":3173
+/* "pywrapfst.pyx":3217
  * 
  * 
- * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class MutableArcIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
   bool (*done)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_uint8 (*flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
+  uint8 (*flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   size_t (*position)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
   void (*seek)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch);
-  void (*set_flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch);
+  void (*set_flags)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch);
   void (*set_value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch);
   PyObject *(*value)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3293
+/* "pywrapfst.pyx":3337
  * 
  * 
- * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
+ * cdef class StateIterator:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
@@ -2133,30 +2152,30 @@ struct __pyx_vtabstruct_9pywrapfst_StateIterator {
   bool (*done)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
-  __pyx_t_10basictypes_int64 (*value)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
+  int64 (*value)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
 
 
-/* "pywrapfst.pyx":4199
+/* "pywrapfst.pyx":4242
  * 
  * 
- * cdef class Compiler(object):             # <<<<<<<<<<<<<<
+ * cdef class Compiler:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst_Compiler {
-  struct __pyx_obj_9pywrapfst__Fst *(*compile)(struct __pyx_obj_9pywrapfst_Compiler *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst_Fst *(*compile)(struct __pyx_obj_9pywrapfst_Compiler *, int __pyx_skip_dispatch);
   void (*write)(struct __pyx_obj_9pywrapfst_Compiler *, PyObject *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4336
+/* "pywrapfst.pyx":4379
  * 
  * 
- * cdef class FarReader(object):             # <<<<<<<<<<<<<<
+ * cdef class FarReader:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
@@ -2167,7 +2186,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
   bool (*error)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
   std::string (*far_type)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
   bool (*find)(struct __pyx_obj_9pywrapfst_FarReader *, PyObject *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst__Fst *(*get_fst)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst_Fst *(*get_fst)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
   std::string (*get_key)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
   void (*next)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
   void (*reset)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch);
@@ -2175,10 +2194,10 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4483
+/* "pywrapfst.pyx":4525
  * 
  * 
- * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
+ * cdef class FarWriter:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
@@ -2186,7 +2205,7 @@ static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_Fa
 struct __pyx_vtabstruct_9pywrapfst_FarWriter {
   std::string (*arc_type)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch);
   void (*close)(struct __pyx_obj_9pywrapfst_FarWriter *);
-  void (*add)(struct __pyx_obj_9pywrapfst_FarWriter *, PyObject *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch);
+  void (*add)(struct __pyx_obj_9pywrapfst_FarWriter *, PyObject *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   bool (*error)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch);
   std::string (*far_type)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch);
 };
@@ -2583,74 +2602,6 @@ static CYTHON_UNUSED PyObject* __Pyx_Method_ClassMethod(PyObject *method);
 #define __Pyx_GetNameInClass(var, nmspace, name)  (var) = __Pyx__GetNameInClass(nmspace, name)
 static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name);
 
-/* FetchCommonType.proto */
-static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
-
-/* CythonFunction.proto */
-#define __Pyx_CyFunction_USED 1
-#define __Pyx_CYFUNCTION_STATICMETHOD  0x01
-#define __Pyx_CYFUNCTION_CLASSMETHOD   0x02
-#define __Pyx_CYFUNCTION_CCLASS        0x04
-#define __Pyx_CyFunction_GetClosure(f)\
-    (((__pyx_CyFunctionObject *) (f))->func_closure)
-#define __Pyx_CyFunction_GetClassObj(f)\
-    (((__pyx_CyFunctionObject *) (f))->func_classobj)
-#define __Pyx_CyFunction_Defaults(type, f)\
-    ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
-#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\
-    ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
-typedef struct {
-    PyCFunctionObject func;
-#if PY_VERSION_HEX < 0x030500A0
-    PyObject *func_weakreflist;
-#endif
-    PyObject *func_dict;
-    PyObject *func_name;
-    PyObject *func_qualname;
-    PyObject *func_doc;
-    PyObject *func_globals;
-    PyObject *func_code;
-    PyObject *func_closure;
-    PyObject *func_classobj;
-    void *defaults;
-    int defaults_pyobjects;
-    int flags;
-    PyObject *defaults_tuple;
-    PyObject *defaults_kwdict;
-    PyObject *(*defaults_getter)(PyObject *);
-    PyObject *func_annotations;
-} __pyx_CyFunctionObject;
-static PyTypeObject *__pyx_CyFunctionType = 0;
-#define __Pyx_CyFunction_Check(obj)  (__Pyx_TypeCheck(obj, __pyx_CyFunctionType))
-#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code)\
-    __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
-static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
-                                      int flags, PyObject* qualname,
-                                      PyObject *self,
-                                      PyObject *module, PyObject *globals,
-                                      PyObject* code);
-static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
-                                                         size_t size,
-                                                         int pyobjects);
-static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
-                                                            PyObject *tuple);
-static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
-                                                             PyObject *dict);
-static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
-                                                              PyObject *dict);
-static int __pyx_CyFunction_init(void);
-
-/* SetNameInClass.proto */
-#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1
-#define __Pyx_SetNameInClass(ns, name, value)\
-    (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value))
-#elif CYTHON_COMPILING_IN_CPYTHON
-#define __Pyx_SetNameInClass(ns, name, value)\
-    (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value))
-#else
-#define __Pyx_SetNameInClass(ns, name, value)  PyObject_SetItem(ns, name, value)
-#endif
-
 /* CLineInTraceback.proto */
 #ifdef CYTHON_CLINE_IN_TRACEBACK
 #define __Pyx_CLineForTraceback(tstate, c_line)  (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0)
@@ -2764,6 +2715,9 @@ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
 /* CIntFromPy.proto */
 static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
 
+/* FetchCommonType.proto */
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
 /* PyObjectGetMethod.proto */
 static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
 
@@ -2859,10 +2813,13 @@ 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_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__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 __pyx_t_10basictypes_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 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*/
@@ -2870,110 +2827,113 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
 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_10basictypes_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 __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_set_name(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_new_name, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, 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*/
 static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, uint64 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
 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__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__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, int __pyx_skip_dispatch); /* 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, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const &__pyx_v_dot); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args); /* proto*/
-static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_output_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, bool __pyx_v_test, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_states(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_text *__pyx_optional_args); /* proto*/
-static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize *__pyx_optional_args); /* proto*/
-static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__project *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__push *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__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_11_MutableFst__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_11_MutableFst__set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* 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 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*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* 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); /* 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); /* proto*/
+static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* 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); /* 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); /* 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); /* 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); /* 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); /* 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); /* proto*/
+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*/
+static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
+static void __pyx_f_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 int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch); /* proto*/
+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); /* proto*/
+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); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs *__pyx_optional_args); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states *__pyx_optional_args); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
+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__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*/
+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); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, size_t __pyx_v_n); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_n); /* proto*/
+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_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*/
 static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc, int __pyx_skip_dispatch); /* proto*/
 static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_expression, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 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*/
@@ -3000,7 +2960,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Module declarations from 'ios' */
 
-/* Module declarations from 'fst' */
+/* Module declarations from 'cpywrapfst' */
 
 /* Module declarations from 'posix.types' */
 
@@ -3008,18 +2968,23 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Module declarations from 'libcpp.cast' */
 
+/* Module declarations from 'memory' */
+
+/* Module declarations from 'utility' */
+
 /* Module declarations from 'pywrapfst' */
 static PyTypeObject *__pyx_ptype_9pywrapfst_Weight = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__SymbolTable = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__FstSymbolTable = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__FstSymbolTableView = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__MutableSymbolTable = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__MutableFstSymbolTable = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__MutableFstSymbolTableView = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_SymbolTable = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst_SymbolTableIterator = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst__SymbolTableIterator = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_EncodeMapper = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__Fst = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__MutableFst = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst_Fst = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst_MutableFst = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst_VectorFst = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_Arc = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_ArcIterator = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst_MutableArcIterator = 0;
@@ -3043,42 +3008,41 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __pyx_obj_9pywrapfst_Weight *, struct __pyx_obj_9pywrapfst_Weight *); /*proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __pyx_obj_9pywrapfst_Weight *, struct __pyx_obj_9pywrapfst_Weight *); /*proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __pyx_obj_9pywrapfst_Weight *, size_t); /*proto*/
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(fst::SymbolTable *, std::shared_ptr<fst::script::EncodeMapperClass> ); /*proto*/
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_FstSymbolTable(fst::SymbolTable *, std::shared_ptr<fst::script::FstClass> ); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__init_MutableFstSymbolTable(fst::SymbolTable *, std::shared_ptr<fst::script::MutableFstClass> ); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(fst::SymbolTable *); /*proto*/
+static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(std::shared_ptr<fst::script::EncodeMapperClass> , bool); /*proto*/
+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_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(fst::script::EncodeMapperClass *); /*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__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__MutableFst *__pyx_f_9pywrapfst__create_Fst(struct __pyx_opt_args_9pywrapfst__create_Fst *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(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__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_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*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args); /*proto*/
-static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equal *__pyx_optional_args); /*proto*/
-static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equivalent *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args); /*proto*/
-static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_isomorphic *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args); /*proto*/
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args); /*proto*/
-static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randequivalent *__pyx_optional_args); /*proto*/
-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 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_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*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args); /*proto*/
+static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equal *__pyx_optional_args); /*proto*/
+static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equivalent *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args); /*proto*/
+static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_isomorphic *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args); /*proto*/
+static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args); /*proto*/
+static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randequivalent *__pyx_optional_args); /*proto*/
+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 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 std::string __pyx_convert_string_from_py_std__in_string(PyObject *); /*proto*/
@@ -3087,18 +3051,18 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_std__in_stri
 static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_std__in_string(std::string const &); /*proto*/
 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<__pyx_t_10basictypes_int64>  __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(PyObject *); /*proto*/
+static std::vector<int64>  __pyx_convert_vector_from_py_int64(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_staticmethod;
-static PyObject *__pyx_builtin_object;
 static PyObject *__pyx_builtin_id;
 static PyObject *__pyx_builtin_TypeError;
 static PyObject *__pyx_builtin_StopIteration;
@@ -3109,16 +3073,14 @@ static const char __pyx_k_w[] = "w";
 static const char __pyx_k__8[] = "";
 static const char __pyx_k_id[] = "id";
 static const char __pyx_k_Arc[] = "Arc";
-static const char __pyx_k_Fst[] = "_Fst";
+static const char __pyx_k_Fst[] = "Fst";
 static const char __pyx_k_One[] = "One";
 static const char __pyx_k_add[] = "add";
 static const char __pyx_k_arc[] = "arc";
-static const char __pyx_k_cls[] = "cls";
 static const char __pyx_k_doc[] = "__doc__";
 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_new[] = "__new__";
 static const char __pyx_k_rhs[] = "rhs";
 static const char __pyx_k_PIPE[] = "PIPE";
 static const char __pyx_k_Tsvg[] = "-Tsvg";
@@ -3147,8 +3109,8 @@ 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_Fst_2[] = "Fst";
 static const char __pyx_k_Popen[] = "Popen";
 static const char __pyx_k_class[] = "__class__";
 static const char __pyx_k_close[] = "close";
@@ -3162,6 +3124,7 @@ static const char __pyx_k_input[] = "input";
 static const char __pyx_k_npath[] = "npath";
 static const char __pyx_k_pairs[] = "pairs";
 static const char __pyx_k_power[] = "power";
+static const char __pyx_k_print[] = "print";
 static const char __pyx_k_props[] = "props";
 static const char __pyx_k_reset[] = "reset";
 static const char __pyx_k_start[] = "start";
@@ -3177,6 +3140,7 @@ 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_create[] = "create";
 static const char __pyx_k_divide[] = "divide";
 static const char __pyx_k_encode[] = "encode";
@@ -3189,7 +3153,6 @@ static const char __pyx_k_member[] = "member";
 static const char __pyx_k_module[] = "__module__";
 static const char __pyx_k_name_2[] = "name";
 static const char __pyx_k_nstate[] = "nstate";
-static const char __pyx_k_object[] = "object";
 static const char __pyx_k_olabel[] = "olabel";
 static const char __pyx_k_opairs[] = "opairs";
 static const char __pyx_k_reduce[] = "__reduce__";
@@ -3226,7 +3189,6 @@ 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_FstError[] = "FstError";
-static const char __pyx_k_Fst_read[] = "Fst.read";
 static const char __pyx_k_KeyError[] = "KeyError";
 static const char __pyx_k_NO_LABEL[] = "NO_LABEL";
 static const char __pyx_k_NoWeight[] = "NoWeight";
@@ -3256,13 +3218,14 @@ 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_weighted[] = "weighted";
 static const char __pyx_k_ARC_FLAGS[] = "ARC_FLAGS";
 static const char __pyx_k_FarReader[] = "FarReader";
 static const char __pyx_k_FarWriter[] = "FarWriter";
-static const char __pyx_k_Fst___new[] = "Fst.__new__";
 static const char __pyx_k_NO_SYMBOL[] = "NO_SYMBOL";
 static const char __pyx_k_TypeError[] = "TypeError";
+static const char __pyx_k_VectorFst[] = "VectorFst";
 static const char __pyx_k_add_state[] = "add_state";
 static const char __pyx_k_add_table[] = "add_table";
 static const char __pyx_k_metaclass[] = "__metaclass__";
@@ -3281,7 +3244,7 @@ static const char __pyx_k_FstIOError[] = "FstIOError";
 static const char __pyx_k_FstOpError[] = "FstOpError";
 static const char __pyx_k_I_EPSILONS[] = "I_EPSILONS";
 static const char __pyx_k_IndexError[] = "IndexError";
-static const char __pyx_k_MutableFst[] = "_MutableFst";
+static const char __pyx_k_MutableFst[] = "MutableFst";
 static const char __pyx_k_NOT_STRING[] = "NOT_STRING";
 static const char __pyx_k_O_EPSILONS[] = "O_EPSILONS";
 static const char __pyx_k_TOP_SORTED[] = "TOP_SORTED";
@@ -3296,6 +3259,7 @@ 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";
@@ -3331,6 +3295,7 @@ 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_ENCODE_LABELS[] = "ENCODE_LABELS";
 static const char __pyx_k_FstIndexError[] = "FstIndexError";
@@ -3346,11 +3311,9 @@ 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";
-static const char __pyx_k_FstSymbolTable[] = "_FstSymbolTable";
 static const char __pyx_k_INITIAL_CYCLIC[] = "INITIAL_CYCLIC";
 static const char __pyx_k_I_LABEL_SORTED[] = "I_LABEL_SORTED";
 static const char __pyx_k_Invalid_weight[] = "Invalid weight";
@@ -3378,7 +3341,6 @@ 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_Key_out_of_order[] = "Key out of order";
 static const char __pyx_k_NOT_COACCESSIBLE[] = "NOT_COACCESSIBLE";
 static const char __pyx_k_Operation_failed[] = "Operation failed";
 static const char __pyx_k_labeled_checksum[] = "labeled_checksum";
@@ -3391,10 +3353,13 @@ 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_call_arc_labeling[] = "call_arc_labeling";
-static const char __pyx_k_set_input_symbols[] = "set_input_symbols";
+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_FstSymbolTableView[] = "_FstSymbolTableView";
 static const char __pyx_k_MutableArcIterator[] = "MutableArcIterator";
 static const char __pyx_k_MutableSymbolTable[] = "_MutableSymbolTable";
 static const char __pyx_k_NOT_I_LABEL_SORTED[] = "NOT_I_LABEL_SORTED";
@@ -3406,12 +3371,11 @@ static const char __pyx_k_Unknown_map_type_r[] = "Unknown map type: {!r}";
 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_set_output_symbols[] = "set_output_symbols";
 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_NON_I_DETERMINISTIC[] = "NON_I_DETERMINISTIC";
 static const char __pyx_k_NON_O_DETERMINISTIC[] = "NON_O_DETERMINISTIC";
-static const char __pyx_k_SymbolTableIterator[] = "SymbolTableIterator";
+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";
@@ -3424,7 +3388,6 @@ 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_Fst_read_from_string[] = "Fst.read_from_string";
 static const char __pyx_k_INTRINSIC_PROPERTIES[] = "INTRINSIC_PROPERTIES";
 static const char __pyx_k_SET_FINAL_PROPERTIES[] = "SET_FINAL_PROPERTIES";
 static const char __pyx_k_SET_START_PROPERTIES[] = "SET_START_PROPERTIES";
@@ -3433,7 +3396,6 @@ 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_DELETE_ARC_PROPERTIES[] = "DELETE_ARC_PROPERTIES";
-static const char __pyx_k_MutableFstSymbolTable[] = "_MutableFstSymbolTable";
 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}>";
@@ -3445,22 +3407,24 @@ 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_EncodeMapperSymbolTable[] = "_EncodeMapperSymbolTable";
 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_Fst_SymbolTable_r_at_0x_x[] = "<Fst SymbolTable {!r} at 0x{:x}>";
 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_x[] = "<SymbolTableIterator at 0x{:x}>";
+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_WEIGHT_INVARIANT_PROPERTIES[] = "WEIGHT_INVARIANT_PROPERTIES";
 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_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_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}";
@@ -3468,11 +3432,11 @@ static const char __pyx_k_increment_subsequential_label[] = "increment_subsequen
 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_EncodeMapper_SymbolTable[] = "<const EncodeMapper SymbolTable {!r} at 0x{:x}>";
-static const char __pyx_k_Fst_arc_type_standard_Construct[] = "\n   Fst(arc_type=\"standard\")\n\n   Constructs an empty FST.\n\n   Args:\n     arc_type: A string indicating the arc type.\n\n   Raises:\n     FstError: Unknown arc type.\n\n   Raises:\n     FstOpError: operation failed.\n   ";
-static const char __pyx_k_const_Fst_SymbolTable_r_at_0x_x[] = "<const Fst SymbolTable {!r} at 0x{:x}>";
+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_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_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";
@@ -3481,7 +3445,6 @@ static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __red
 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__siter_self__table_cannot_b[] = "self._siter,self._table 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 PyObject *__pyx_n_s_ACCEPTOR;
@@ -3514,6 +3477,7 @@ static PyObject *__pyx_n_s_Compiler;
 static PyObject *__pyx_kp_u_Conversion_to_r_failed;
 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_kp_u_Dot_rendering_failed_s;
 static PyObject *__pyx_n_s_ENCODE_FLAGS;
 static PyObject *__pyx_n_s_ENCODE_LABELS;
@@ -3523,7 +3487,7 @@ static PyObject *__pyx_n_s_ERROR;
 static PyObject *__pyx_n_s_EXPANDED;
 static PyObject *__pyx_n_s_EXTRINSIC_PROPERTIES;
 static PyObject *__pyx_n_s_EncodeMapper;
-static PyObject *__pyx_n_s_EncodeMapperSymbolTable;
+static PyObject *__pyx_n_s_EncodeMapperSymbolTableView;
 static PyObject *__pyx_kp_u_EncodeMapper_at_0x_x;
 static PyObject *__pyx_n_s_FST_PROPERTIES;
 static PyObject *__pyx_n_s_FarReader;
@@ -3538,14 +3502,9 @@ 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_FstSymbolTable;
-static PyObject *__pyx_n_s_Fst_2;
-static PyObject *__pyx_kp_u_Fst_SymbolTable_r_at_0x_x;
-static PyObject *__pyx_n_s_Fst___new;
-static PyObject *__pyx_kp_s_Fst_arc_type_standard_Construct;
+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_n_s_Fst_read;
-static PyObject *__pyx_n_s_Fst_read_from_string;
 static PyObject *__pyx_n_s_INITIAL_ACYCLIC;
 static PyObject *__pyx_n_s_INITIAL_CYCLIC;
 static PyObject *__pyx_n_s_INTRINSIC_PROPERTIES;
@@ -3560,13 +3519,12 @@ static PyObject *__pyx_kp_u_Incompatible_or_invalid_weight_t;
 static PyObject *__pyx_n_s_IndexError;
 static PyObject *__pyx_kp_u_Invalid_weight;
 static PyObject *__pyx_n_s_KeyError;
-static PyObject *__pyx_kp_u_Key_out_of_order;
 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_n_s_MutableFst;
-static PyObject *__pyx_n_s_MutableFstSymbolTable;
+static PyObject *__pyx_n_s_MutableFstSymbolTableView;
 static PyObject *__pyx_n_s_MutableSymbolTable;
 static PyObject *__pyx_n_s_NEG_TRINARY_PROPERTIES;
 static PyObject *__pyx_n_s_NON_I_DETERMINISTIC;
@@ -3616,6 +3574,7 @@ static PyObject *__pyx_n_s_SymbolTable;
 static PyObject *__pyx_n_s_SymbolTableIterator;
 static PyObject *__pyx_kp_u_SymbolTableIterator_at_0x_x;
 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;
@@ -3631,7 +3590,9 @@ static PyObject *__pyx_kp_u_Unknown_queue_type_r;
 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_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;
@@ -3650,6 +3611,7 @@ 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;
@@ -3664,13 +3626,12 @@ static PyObject *__pyx_n_s_class;
 static PyObject *__pyx_n_s_cline_in_traceback;
 static PyObject *__pyx_n_s_close;
 static PyObject *__pyx_n_s_closure_plus;
-static PyObject *__pyx_n_s_cls;
 static PyObject *__pyx_n_s_communicate;
 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_SymbolTable;
-static PyObject *__pyx_kp_u_const_Fst_SymbolTable_r_at_0x_x;
+static PyObject *__pyx_kp_u_const_EncodeMapper_SymbolTableV;
+static PyObject *__pyx_kp_u_const_Fst_SymbolTableView_r_at;
 static PyObject *__pyx_n_s_copy;
 static PyObject *__pyx_n_s_create;
 static PyObject *__pyx_n_b_default;
@@ -3738,7 +3699,6 @@ 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_s_new;
 static PyObject *__pyx_n_s_new_isymbols;
 static PyObject *__pyx_n_s_new_osymbols;
 static PyObject *__pyx_n_s_next;
@@ -3754,7 +3714,6 @@ static PyObject *__pyx_n_s_num_output_epsilons;
 static PyObject *__pyx_n_s_num_states;
 static PyObject *__pyx_n_s_num_symbols;
 static PyObject *__pyx_n_s_numbers;
-static PyObject *__pyx_n_s_object;
 static PyObject *__pyx_n_s_olabel;
 static PyObject *__pyx_n_s_old_isymbols;
 static PyObject *__pyx_n_s_old_osymbols;
@@ -3770,13 +3729,13 @@ static PyObject *__pyx_n_s_potentials;
 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;
@@ -3808,22 +3767,23 @@ static PyObject *__pyx_kp_s_self__aiter_self__mfst_cannot_be;
 static PyObject *__pyx_kp_s_self__arc_cannot_be_converted_to;
 static PyObject *__pyx_kp_s_self__fst_self__siter_cannot_be;
 static PyObject *__pyx_kp_s_self__reader_cannot_be_converted;
-static PyObject *__pyx_kp_s_self__siter_self__table_cannot_b;
+static PyObject *__pyx_kp_s_self__siter_cannot_be_converted;
 static PyObject *__pyx_kp_s_self__weight_cannot_be_converted;
 static PyObject *__pyx_kp_s_self__writer_cannot_be_converted;
 static PyObject *__pyx_n_s_send;
 static PyObject *__pyx_n_s_set_flags;
-static PyObject *__pyx_n_s_set_input_symbols;
 static PyObject *__pyx_n_s_set_name;
-static PyObject *__pyx_n_s_set_output_symbols;
 static PyObject *__pyx_n_s_set_value;
 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_s_start;
 static PyObject *__pyx_n_s_state;
@@ -3855,7 +3815,9 @@ static PyObject *__pyx_n_b_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_type;
 static PyObject *__pyx_n_s_weighted;
@@ -3898,12 +3860,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
 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 PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__FstSymbolTable *__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, __pyx_t_10basictypes_int64 __pyx_v_key); /* 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_4set_name(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_new_name); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_v_self); /* 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 */
 static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
@@ -3912,17 +3874,12 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
 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_19SymbolTableIterator___repr__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_8done(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_10next(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_16value(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* 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 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 */
+static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 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); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
@@ -3930,7 +3887,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, uint64 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
@@ -3940,83 +3897,84 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
 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_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_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, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_30output_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, bool __pyx_v_test); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(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_4_Fst_40verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_project_output); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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_11_MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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_11_MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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_11_MutableFst_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_11_MutableFst_58set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source); /* 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 */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
+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_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 */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state); /* proto */
+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_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_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 */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, bool __pyx_v_closure_plus); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_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_18delete_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_states); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state); /* proto */
+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_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_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_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_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_cls, PyObject *__pyx_v_arc_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__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, __pyx_t_10basictypes_int64 __pyx_v_ilabel, __pyx_t_10basictypes_int64 __pyx_v_olabel, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nextstate); /* 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 */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value); /* proto */
+static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value); /* proto */
+static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, PyObject *__pyx_v_weight); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value); /* proto */
+static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
+static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
@@ -4025,12 +3983,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_ifst, __pyx_t_10basictypes_int64 __pyx_v_state); /* proto */
+static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
@@ -4038,13 +3996,13 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, size_t __pyx_v_a); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
@@ -4053,27 +4011,27 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_34equal(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_36equivalent(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_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
-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, __pyx_t_10basictypes_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, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_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, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight); /* 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, __pyx_t_10basictypes_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, __pyx_t_10basictypes_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, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_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 PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, int64 __pyx_v_nstate, int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int64 __pyx_v_nstate, int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_34equal(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_36equivalent(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_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect); /* proto */
+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_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 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 */
@@ -4097,24 +4055,25 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
 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 */
-static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
-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); /* proto */
+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); /* proto */
 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__EncodeMapperSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst__FstSymbolTable(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*/
-static PyObject *__pyx_tp_new_9pywrapfst__MutableFstSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(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_SymbolTableIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst__SymbolTableIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_EncodeMapper(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst__Fst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst__MutableFst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst_Fst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst_MutableFst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst_VectorFst(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_Arc(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_ArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_MutableArcIterator(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
@@ -4123,49 +4082,50 @@ 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 __pyx_t_10basictypes_int64 __pyx_k__3;
-static float __pyx_k__9;
+static PyObject *__pyx_int_2;
+static int64 __pyx_k__3;
 static float __pyx_k__10;
 static float __pyx_k__11;
-static __pyx_t_10basictypes_int64 __pyx_k__12;
-static float __pyx_k__13;
-static __pyx_t_10basictypes_int64 __pyx_k__14;
-static float __pyx_k__15;
+static float __pyx_k__12;
+static int64 __pyx_k__13;
+static float __pyx_k__14;
+static int64 __pyx_k__15;
 static float __pyx_k__16;
-static __pyx_t_10basictypes_int64 __pyx_k__17;
-static float __pyx_k__18;
-static __pyx_t_10basictypes_int64 __pyx_k__19;
-static float __pyx_k__20;
-static float __pyx_k__29;
+static float __pyx_k__17;
+static int64 __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 __pyx_t_10basictypes_int64 __pyx_k__32;
-static float __pyx_k__33;
-static __pyx_t_10basictypes_int64 __pyx_k__34;
-static float __pyx_k__35;
+static float __pyx_k__32;
+static int64 __pyx_k__33;
+static float __pyx_k__34;
+static int64 __pyx_k__35;
 static float __pyx_k__36;
 static float __pyx_k__37;
 static float __pyx_k__38;
-static __pyx_t_10basictypes_int64 __pyx_k__39;
-static float __pyx_k__40;
+static float __pyx_k__39;
+static int64 __pyx_k__40;
 static float __pyx_k__41;
-static __pyx_t_10basictypes_int32 __pyx_k__42;
-static __pyx_t_10basictypes_int32 __pyx_k__43;
-static float __pyx_k__44;
-static __pyx_t_10basictypes_int64 __pyx_k__45;
-static float __pyx_k__46;
-static __pyx_t_10basictypes_int64 __pyx_k__47;
-static float __pyx_k__48;
-static __pyx_t_10basictypes_int64 __pyx_k__49;
-static std::string __pyx_k__50;
+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 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 PyObject *__pyx_tuple__4;
 static PyObject *__pyx_tuple__5;
 static PyObject *__pyx_tuple__6;
 static PyObject *__pyx_tuple__7;
-static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__9;
 static PyObject *__pyx_tuple__22;
 static PyObject *__pyx_tuple__23;
 static PyObject *__pyx_tuple__24;
@@ -4173,35 +4133,29 @@ static PyObject *__pyx_tuple__25;
 static PyObject *__pyx_tuple__26;
 static PyObject *__pyx_tuple__27;
 static PyObject *__pyx_tuple__28;
-static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__29;
 static PyObject *__pyx_tuple__53;
 static PyObject *__pyx_tuple__54;
 static PyObject *__pyx_tuple__55;
 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__69;
-static PyObject *__pyx_tuple__71;
-static PyObject *__pyx_tuple__72;
-static PyObject *__pyx_tuple__74;
-static PyObject *__pyx_tuple__76;
-static PyObject *__pyx_codeobj__59;
+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__70;
-static PyObject *__pyx_codeobj__73;
-static PyObject *__pyx_codeobj__75;
-static PyObject *__pyx_codeobj__77;
+static PyObject *__pyx_codeobj__69;
+static PyObject *__pyx_codeobj__71;
 /* Late includes */
 
-/* "pywrapfst.pyx":145
+/* "pywrapfst.pyx":150
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4222,7 +4176,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("tostring", 0);
 
-  /* "pywrapfst.pyx":165
+  /* "pywrapfst.pyx":170
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4233,18 +4187,18 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":166
+    /* "pywrapfst.pyx":171
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):
  *     return data             # <<<<<<<<<<<<<<
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 166, __pyx_L1_error)
+    __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_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":165
+    /* "pywrapfst.pyx":170
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4253,7 +4207,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":167
+  /* "pywrapfst.pyx":172
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4264,14 +4218,14 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":168
+    /* "pywrapfst.pyx":173
  *     return data
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")             # <<<<<<<<<<<<<<
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))
  * 
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 168, __pyx_L1_error)
+    __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))) {
@@ -4285,15 +4239,15 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
     }
     __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, 168, __pyx_L1_error)
+    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, 168, __pyx_L1_error)
+    __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;
 
-    /* "pywrapfst.pyx":167
+    /* "pywrapfst.pyx":172
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4302,16 +4256,16 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":169
+  /* "pywrapfst.pyx":174
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 169, __pyx_L1_error)
+  __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, 169, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_7);
   __pyx_t_8 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -4325,7 +4279,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   }
   __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, 169, __pyx_L1_error)
+  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;
@@ -4341,14 +4295,14 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   __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, 169, __pyx_L1_error)
+  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 174, __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, 169, __pyx_L1_error)
+  __PYX_ERR(0, 174, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":145
+  /* "pywrapfst.pyx":150
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4370,7 +4324,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":172
+/* "pywrapfst.pyx":177
  * 
  * 
  * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4391,7 +4345,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("weight_tostring", 0);
 
-  /* "pywrapfst.pyx":196
+  /* "pywrapfst.pyx":201
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4402,18 +4356,18 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":197
+    /* "pywrapfst.pyx":202
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):
  *     return data             # <<<<<<<<<<<<<<
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 197, __pyx_L1_error)
+    __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_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":196
+    /* "pywrapfst.pyx":201
  *   """
  *   # A Python bytestring can be implicitly cast to a C++ string.
  *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
@@ -4422,7 +4376,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":198
+  /* "pywrapfst.pyx":203
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4433,14 +4387,14 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":199
+    /* "pywrapfst.pyx":204
  *     return data
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")             # <<<<<<<<<<<<<<
  *   elif isinstance(data, numbers.Number):
  *     return str(data).encode("utf8")
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 199, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -4454,15 +4408,15 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
     }
     __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, 199, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 204, __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, 199, __pyx_L1_error)
+    __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":198
+    /* "pywrapfst.pyx":203
  *   if isinstance(data, bytes):
  *     return data
  *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
@@ -4471,41 +4425,41 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":200
+  /* "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))
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 200, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 205, __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, 200, __pyx_L1_error)
+  __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_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, 200, __pyx_L1_error)
+  __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_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":201
+    /* "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))
  * 
  */
-    __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 201, __pyx_L1_error)
+    __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, 201, __pyx_L1_error)
+    __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, 201, __pyx_L1_error)
+    __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":200
+    /* "pywrapfst.pyx":205
  *   elif isinstance(data, unicode):
  *     return data.encode("utf8")
  *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
@@ -4514,16 +4468,16 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
  */
   }
 
-  /* "pywrapfst.pyx":202
+  /* "pywrapfst.pyx":207
  *   elif isinstance(data, numbers.Number):
  *     return str(data).encode("utf8")
  *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 202, __pyx_L1_error)
+  __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, 202, __pyx_L1_error)
+  __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))) {
@@ -4537,7 +4491,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   }
   __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, 202, __pyx_L1_error)
+  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;
@@ -4553,14 +4507,14 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   __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, 202, __pyx_L1_error)
+  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, 202, __pyx_L1_error)
+  __PYX_ERR(0, 207, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":172
+  /* "pywrapfst.pyx":177
  * 
  * 
  * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4582,7 +4536,7 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":205
+/* "pywrapfst.pyx":210
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4603,7 +4557,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_compose_filter", 0);
 
-  /* "pywrapfst.pyx":227
+  /* "pywrapfst.pyx":232
  *   """
  *   cdef fst.ComposeFilter compose_filter_enum
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
@@ -4613,26 +4567,26 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_t_1 = ((!(fst::script::GetComposeFilter(__pyx_v_compose_filter, (&__pyx_v_compose_filter_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":228
+    /* "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
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 228, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 233, __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, 228, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_5);
 
-    /* "pywrapfst.pyx":229
+    /* "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, 229, __pyx_L1_error)
+    __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))) {
@@ -4647,7 +4601,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
     __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, 228, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 233, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4663,14 +4617,14 @@ 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, 228, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __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, 228, __pyx_L1_error)
+    __PYX_ERR(0, 233, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":227
+    /* "pywrapfst.pyx":232
  *   """
  *   cdef fst.ComposeFilter compose_filter_enum
  *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
@@ -4679,7 +4633,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
  */
   }
 
-  /* "pywrapfst.pyx":230
+  /* "pywrapfst.pyx":235
  *     raise FstArgError("Unknown compose filter type: {!r}".format(
  *         compose_filter))
  *   return compose_filter_enum             # <<<<<<<<<<<<<<
@@ -4689,7 +4643,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __pyx_r = __pyx_v_compose_filter_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":205
+  /* "pywrapfst.pyx":210
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4712,7 +4666,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":233
+/* "pywrapfst.pyx":238
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4733,7 +4687,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_determinize_type", 0);
 
-  /* "pywrapfst.pyx":249
+  /* "pywrapfst.pyx":254
  *   """
  *   cdef fst.DeterminizeType det_type_enum
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
@@ -4743,18 +4697,18 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_t_1 = ((!(fst::script::GetDeterminizeType(__pyx_v_det_type, (&__pyx_v_det_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":250
+    /* "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
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 250, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 255, __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, 250, __pyx_L1_error)
+    __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_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, 250, __pyx_L1_error)
+    __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))) {
@@ -4769,7 +4723,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
     __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, 250, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 255, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4785,14 +4739,14 @@ 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, 250, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 255, __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, 250, __pyx_L1_error)
+    __PYX_ERR(0, 255, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":249
+    /* "pywrapfst.pyx":254
  *   """
  *   cdef fst.DeterminizeType det_type_enum
  *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
@@ -4801,7 +4755,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
  */
   }
 
-  /* "pywrapfst.pyx":251
+  /* "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             # <<<<<<<<<<<<<<
@@ -4811,7 +4765,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __pyx_r = __pyx_v_det_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":233
+  /* "pywrapfst.pyx":238
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4834,7 +4788,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":254
+/* "pywrapfst.pyx":259
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4855,7 +4809,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_queue_type", 0);
 
-  /* "pywrapfst.pyx":273
+  /* "pywrapfst.pyx":278
  *   """
  *   cdef fst.QueueType queue_type_enum
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
@@ -4865,18 +4819,18 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_t_1 = ((!(fst::script::GetQueueType(__pyx_v_queue_type, (&__pyx_v_queue_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":274
+    /* "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
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 274, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 279, __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, 274, __pyx_L1_error)
+    __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_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, 274, __pyx_L1_error)
+    __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))) {
@@ -4891,7 +4845,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
     __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, 274, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 279, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4907,14 +4861,14 @@ 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, 274, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 279, __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, 274, __pyx_L1_error)
+    __PYX_ERR(0, 279, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":273
+    /* "pywrapfst.pyx":278
  *   """
  *   cdef fst.QueueType queue_type_enum
  *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
@@ -4923,7 +4877,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
  */
   }
 
-  /* "pywrapfst.pyx":275
+  /* "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             # <<<<<<<<<<<<<<
@@ -4933,7 +4887,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __pyx_r = __pyx_v_queue_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":254
+  /* "pywrapfst.pyx":259
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4956,7 +4910,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":278
+/* "pywrapfst.pyx":283
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -4977,7 +4931,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_rand_arc_selection", 0);
 
-  /* "pywrapfst.pyx":298
+  /* "pywrapfst.pyx":303
  *   """
  *   cdef fst.RandArcSelection select_enum
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
@@ -4987,18 +4941,18 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_t_1 = ((!(fst::script::GetRandArcSelection(__pyx_v_select, (&__pyx_v_select_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":299
+    /* "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
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 299, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 304, __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, 299, __pyx_L1_error)
+    __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_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, 299, __pyx_L1_error)
+    __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))) {
@@ -5013,7 +4967,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
     __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, 299, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 304, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5029,14 +4983,14 @@ 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, 299, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 304, __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, 299, __pyx_L1_error)
+    __PYX_ERR(0, 304, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":298
+    /* "pywrapfst.pyx":303
  *   """
  *   cdef fst.RandArcSelection select_enum
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
@@ -5045,7 +4999,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
  */
   }
 
-  /* "pywrapfst.pyx":300
+  /* "pywrapfst.pyx":305
  *   if not fst.GetRandArcSelection(select, addr(select_enum)):
  *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))
  *   return select_enum             # <<<<<<<<<<<<<<
@@ -5055,7 +5009,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __pyx_r = __pyx_v_select_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":278
+  /* "pywrapfst.pyx":283
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -5078,7 +5032,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":303
+/* "pywrapfst.pyx":308
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5099,7 +5053,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_replace_label_type", 0);
 
-  /* "pywrapfst.pyx":324
+  /* "pywrapfst.pyx":329
  *   """
  *   cdef fst.ReplaceLabelType replace_label_type_enum
  *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
@@ -5109,26 +5063,26 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_t_1 = ((!(fst::script::GetReplaceLabelType(__pyx_v_replace_label_type, __pyx_v_epsilon_on_replace, (&__pyx_v_replace_label_type_enum)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":326
+    /* "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
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 326, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 331, __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, 326, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_5);
 
-    /* "pywrapfst.pyx":327
+    /* "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, 327, __pyx_L1_error)
+    __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))) {
@@ -5143,7 +5097,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(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, 326, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 331, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5159,14 +5113,14 @@ 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, 326, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 331, __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, 326, __pyx_L1_error)
+    __PYX_ERR(0, 331, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":324
+    /* "pywrapfst.pyx":329
  *   """
  *   cdef fst.ReplaceLabelType replace_label_type_enum
  *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
@@ -5175,7 +5129,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
  */
   }
 
-  /* "pywrapfst.pyx":328
+  /* "pywrapfst.pyx":333
  *     raise FstArgError("Unknown replace label type: {!r}".format(
  *                       replace_label_type))
  *   return replace_label_type_enum             # <<<<<<<<<<<<<<
@@ -5185,7 +5139,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __pyx_r = __pyx_v_replace_label_type_enum;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":303
+  /* "pywrapfst.pyx":308
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5208,7 +5162,7 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":354
+/* "pywrapfst.pyx":359
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5242,7 +5196,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":355
+  /* "pywrapfst.pyx":360
  * 
  *   def __repr__(self):
  *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),             # <<<<<<<<<<<<<<
@@ -5250,29 +5204,29 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
  * 
  */
   __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, 355, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "type");
-    __PYX_ERR(0, 355, __pyx_L1_error)
+    __PYX_ERR(0, 360, __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, 355, __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 355, __pyx_L1_error)
+    __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, 355, __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_GOTREF(__pyx_t_4);
 
-  /* "pywrapfst.pyx":356
+  /* "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, 356, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_5);
   __pyx_t_6 = NULL;
   __pyx_t_7 = 0;
@@ -5289,7 +5243,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   #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, 355, __pyx_L1_error)
+    __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;
@@ -5300,7 +5254,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   #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, 355, __pyx_L1_error)
+    __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;
@@ -5309,7 +5263,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   } else
   #endif
   {
-    __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 355, __pyx_L1_error)
+    __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;
@@ -5323,7 +5277,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
     __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, 355, __pyx_L1_error)
+    __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;
   }
@@ -5332,7 +5286,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":354
+  /* "pywrapfst.pyx":359
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -5357,7 +5311,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":358
+/* "pywrapfst.pyx":363
  *                                              id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5384,7 +5338,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":359
+  /* "pywrapfst.pyx":364
  * 
  *   def __str__(self):
  *     return self.to_string()             # <<<<<<<<<<<<<<
@@ -5394,15 +5348,15 @@ 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, 359, __pyx_L1_error)
+    __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, 359, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":358
+  /* "pywrapfst.pyx":363
  *                                              id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
@@ -5421,7 +5375,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":364
+/* "pywrapfst.pyx":369
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5449,7 +5403,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__float__", 0);
 
-  /* "pywrapfst.pyx":365
+  /* "pywrapfst.pyx":370
  * 
  *   def __float__(self):
  *     return float(self.to_string())             # <<<<<<<<<<<<<<
@@ -5459,18 +5413,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, 365, __pyx_L1_error)
+    __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, 365, __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_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 365, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 370, __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":364
+  /* "pywrapfst.pyx":369
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5490,7 +5444,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":367
+/* "pywrapfst.pyx":372
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5529,11 +5483,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, 367, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 372, __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, 367, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 372, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -5546,7 +5500,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, 367, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 372, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Weight.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -5566,7 +5520,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   std::string __pyx_t_2;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":368
+  /* "pywrapfst.pyx":373
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5575,20 +5529,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, 368, __pyx_L1_error)
+    __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, 368, __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)
 
-  /* "pywrapfst.pyx":369
+  /* "pywrapfst.pyx":374
  *   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, 369, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 374, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":368
+  /* "pywrapfst.pyx":373
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5597,7 +5551,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":370
+  /* "pywrapfst.pyx":375
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weight_tostring(weight)))
  *     self._check_weight()             # <<<<<<<<<<<<<<
@@ -5606,11 +5560,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, 370, __pyx_L1_error)
+    __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, 370, __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)
 
-  /* "pywrapfst.pyx":367
+  /* "pywrapfst.pyx":372
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5629,7 +5583,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":372
+/* "pywrapfst.pyx":377
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5645,7 +5599,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_check_weight", 0);
 
-  /* "pywrapfst.pyx":373
+  /* "pywrapfst.pyx":378
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5654,19 +5608,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, 373, __pyx_L1_error)
+    __PYX_ERR(0, 378, __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":374
+    /* "pywrapfst.pyx":379
  *   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, 374, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 379, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5680,14 +5634,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, 374, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 379, __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, 374, __pyx_L1_error)
+    __PYX_ERR(0, 379, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":373
+    /* "pywrapfst.pyx":378
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5696,7 +5650,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":375
+  /* "pywrapfst.pyx":380
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5705,19 +5659,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, 375, __pyx_L1_error)
+    __PYX_ERR(0, 380, __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":376
+    /* "pywrapfst.pyx":381
  *       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, 376, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 381, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5731,14 +5685,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, 376, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 381, __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, 376, __pyx_L1_error)
+    __PYX_ERR(0, 381, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":375
+    /* "pywrapfst.pyx":380
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5747,7 +5701,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":372
+  /* "pywrapfst.pyx":377
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5766,7 +5720,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":378
+/* "pywrapfst.pyx":383
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -5793,7 +5747,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, 378, __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, 383, __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));
@@ -5810,10 +5764,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, 378, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 383, __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, 378, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 383, __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;
@@ -5832,19 +5786,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":384
+  /* "pywrapfst.pyx":389
  *     Returns a copy of the Weight.
  *     """
  *     cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *     result._weight.reset(new fst.WeightClass(deref(self._weight)))
  *     return result
  */
-  __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, 384, __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, 389, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":385
+  /* "pywrapfst.pyx":390
  *     """
  *     cdef Weight result = Weight.__new__(Weight)
  *     result._weight.reset(new fst.WeightClass(deref(self._weight)))             # <<<<<<<<<<<<<<
@@ -5853,15 +5807,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 385, __pyx_L1_error)
+    __PYX_ERR(0, 390, __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, 385, __pyx_L1_error)
+    __PYX_ERR(0, 390, __pyx_L1_error)
   }
   __pyx_v_result->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_weight)));
 
-  /* "pywrapfst.pyx":386
+  /* "pywrapfst.pyx":391
  *     cdef Weight result = Weight.__new__(Weight)
  *     result._weight.reset(new fst.WeightClass(deref(self._weight)))
  *     return result             # <<<<<<<<<<<<<<
@@ -5873,7 +5827,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":378
+  /* "pywrapfst.pyx":383
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -5916,7 +5870,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   PyObject *__pyx_t_1 = NULL;
   __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, 378, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -5933,7 +5887,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":392
+/* "pywrapfst.pyx":397
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -5961,7 +5915,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("Zero", 0);
 
-  /* "pywrapfst.pyx":398
+  /* "pywrapfst.pyx":403
  *     Constructs semiring zero.
  *     """
  *     return _Zero(weight_type)             # <<<<<<<<<<<<<<
@@ -5969,13 +5923,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, 398, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":392
+  /* "pywrapfst.pyx":397
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -5994,7 +5948,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":401
+/* "pywrapfst.pyx":406
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6022,7 +5976,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("One", 0);
 
-  /* "pywrapfst.pyx":407
+  /* "pywrapfst.pyx":412
  *     Constructs semiring One.
  *     """
  *     return _One(weight_type)             # <<<<<<<<<<<<<<
@@ -6030,13 +5984,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, 407, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":401
+  /* "pywrapfst.pyx":406
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6055,7 +6009,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":410
+/* "pywrapfst.pyx":415
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6083,7 +6037,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("NoWeight", 0);
 
-  /* "pywrapfst.pyx":416
+  /* "pywrapfst.pyx":421
  *     Constructs a non-member weight in the semiring.
  *     """
  *     return _NoWeight(weight_type)             # <<<<<<<<<<<<<<
@@ -6091,13 +6045,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, 416, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":410
+  /* "pywrapfst.pyx":415
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6116,7 +6070,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":418
+/* "pywrapfst.pyx":423
  *     return _NoWeight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6130,7 +6084,7 @@ static PyObject *__pyx_pw_9pywrapfst_6Weight_17__eq__(PyObject *__pyx_v_w1, PyOb
   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, 418, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 423, __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 */
@@ -6148,7 +6102,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__eq__", 0);
 
-  /* "pywrapfst.pyx":419
+  /* "pywrapfst.pyx":424
  * 
  *   def __eq__(Weight w1, Weight w2):
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))             # <<<<<<<<<<<<<<
@@ -6158,19 +6112,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, 419, __pyx_L1_error)
+    __PYX_ERR(0, 424, __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, 419, __pyx_L1_error)
+    __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, 419, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":418
+  /* "pywrapfst.pyx":423
  *     return _NoWeight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6189,7 +6143,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":421
+/* "pywrapfst.pyx":426
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6203,7 +6157,7 @@ static PyObject *__pyx_pw_9pywrapfst_6Weight_19__ne__(PyObject *__pyx_v_w1, PyOb
   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, 421, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 426, __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 */
@@ -6222,7 +6176,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("__ne__", 0);
 
-  /* "pywrapfst.pyx":422
+  /* "pywrapfst.pyx":427
  * 
  *   def __ne__(Weight w1, Weight w2):
  *     return not w1 == w2             # <<<<<<<<<<<<<<
@@ -6230,16 +6184,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, 422, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 422, __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, 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_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, 422, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); 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":421
+  /* "pywrapfst.pyx":426
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6258,7 +6212,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":424
+/* "pywrapfst.pyx":429
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6285,7 +6239,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, 424, __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, 429, __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);
@@ -6301,10 +6255,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, 424, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 429, __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, 424, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6323,7 +6277,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":425
+  /* "pywrapfst.pyx":430
  * 
  *   cpdef string to_string(self):
  *     return self._weight.get().ToString()             # <<<<<<<<<<<<<<
@@ -6332,12 +6286,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, 425, __pyx_L1_error)
+    __PYX_ERR(0, 430, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->ToString();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":424
+  /* "pywrapfst.pyx":429
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6377,7 +6331,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __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, 424, __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, 429, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6394,7 +6348,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":427
+/* "pywrapfst.pyx":432
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6421,7 +6375,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, 427, __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, 432, __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);
@@ -6437,10 +6391,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, 427, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 432, __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, 427, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6459,7 +6413,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     #endif
   }
 
-  /* "pywrapfst.pyx":432
+  /* "pywrapfst.pyx":437
  *     Returns a string indicating the weight type.
  *     """
  *     return self._weight.get().Type()             # <<<<<<<<<<<<<<
@@ -6468,12 +6422,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, 432, __pyx_L1_error)
+    __PYX_ERR(0, 437, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Type();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":427
+  /* "pywrapfst.pyx":432
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6514,7 +6468,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_1 = NULL;
   __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, 427, __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, 432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6531,7 +6485,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":434
+/* "pywrapfst.pyx":439
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6558,7 +6512,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, 434, __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, 439, __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);
@@ -6574,10 +6528,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, 434, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 439, __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, 434, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6596,7 +6550,7 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
     #endif
   }
 
-  /* "pywrapfst.pyx":435
+  /* "pywrapfst.pyx":440
  * 
  *   cpdef bool member(self):
  *     return self._weight.get().Member()             # <<<<<<<<<<<<<<
@@ -6605,12 +6559,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, 435, __pyx_L1_error)
+    __PYX_ERR(0, 440, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Member();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":434
+  /* "pywrapfst.pyx":439
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6650,7 +6604,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_24member(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __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, 434, __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, 439, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6774,7 +6728,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_28__setstate_cython__(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":438
+/* "pywrapfst.pyx":443
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6789,19 +6743,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_plus", 0);
 
-  /* "pywrapfst.pyx":439
+  /* "pywrapfst.pyx":444
  * 
  * 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))))
  */
-  __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, 439, __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, 444, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":440
+  /* "pywrapfst.pyx":445
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -6810,14 +6764,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 440, __pyx_L1_error)
+    __PYX_ERR(0, 445, __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, 440, __pyx_L1_error)
+    __PYX_ERR(0, 445, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":441
+  /* "pywrapfst.pyx":446
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                     deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -6826,10 +6780,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 441, __pyx_L1_error)
+    __PYX_ERR(0, 446, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":440
+  /* "pywrapfst.pyx":445
  * cdef Weight _plus(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -6838,7 +6792,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Plus((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":442
+  /* "pywrapfst.pyx":447
  *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  *                                                     deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -6850,7 +6804,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":438
+  /* "pywrapfst.pyx":443
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6870,7 +6824,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":445
+/* "pywrapfst.pyx":450
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6911,11 +6865,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, 445, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 450, __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, 445, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 450, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -6928,14 +6882,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, 445, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 450, __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, 445, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 445, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_plus(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -6954,19 +6908,19 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("plus", 0);
 
-  /* "pywrapfst.pyx":465
+  /* "pywrapfst.pyx":470
  *     FstBadWeightError: invalid weight.
  *   """
  *   cdef Weight result = _plus(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 465, __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, 470, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":466
+  /* "pywrapfst.pyx":471
  *   """
  *   cdef Weight result = _plus(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -6975,11 +6929,11 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 466, __pyx_L1_error)
+    __PYX_ERR(0, 471, __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, 466, __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)
 
-  /* "pywrapfst.pyx":467
+  /* "pywrapfst.pyx":472
  *   cdef Weight result = _plus(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -6991,7 +6945,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":450
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7011,7 +6965,7 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":470
+/* "pywrapfst.pyx":475
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7026,19 +6980,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_times", 0);
 
-  /* "pywrapfst.pyx":471
+  /* "pywrapfst.pyx":476
  * 
  * 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))))
  */
-  __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, 471, __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, 476, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":472
+  /* "pywrapfst.pyx":477
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7047,14 +7001,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 472, __pyx_L1_error)
+    __PYX_ERR(0, 477, __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, 472, __pyx_L1_error)
+    __PYX_ERR(0, 477, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":473
+  /* "pywrapfst.pyx":478
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                      deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7063,10 +7017,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 473, __pyx_L1_error)
+    __PYX_ERR(0, 478, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":472
+  /* "pywrapfst.pyx":477
  * cdef Weight _times(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7075,7 +7029,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Times((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":474
+  /* "pywrapfst.pyx":479
  *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  *                                                      deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -7087,7 +7041,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":470
+  /* "pywrapfst.pyx":475
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7107,7 +7061,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":477
+/* "pywrapfst.pyx":482
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7148,11 +7102,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, 477, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 482, __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, 477, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 482, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7165,14 +7119,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, 477, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 482, __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, 477, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 477, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_2times(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7191,19 +7145,19 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("times", 0);
 
-  /* "pywrapfst.pyx":497
+  /* "pywrapfst.pyx":502
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _times(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 497, __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, 502, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":498
+  /* "pywrapfst.pyx":503
  *   """
  *   cdef Weight result = _times(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7212,11 +7166,11 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 498, __pyx_L1_error)
+    __PYX_ERR(0, 503, __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, 498, __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)
 
-  /* "pywrapfst.pyx":499
+  /* "pywrapfst.pyx":504
  *   cdef Weight result = _times(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7228,7 +7182,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":482
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7248,7 +7202,7 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":502
+/* "pywrapfst.pyx":507
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7263,19 +7217,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_divide", 0);
 
-  /* "pywrapfst.pyx":503
+  /* "pywrapfst.pyx":508
  * 
  * 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))))
  */
-  __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, 503, __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, 508, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":504
+  /* "pywrapfst.pyx":509
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7284,14 +7238,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 504, __pyx_L1_error)
+    __PYX_ERR(0, 509, __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, 504, __pyx_L1_error)
+    __PYX_ERR(0, 509, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":505
+  /* "pywrapfst.pyx":510
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                       deref(rhs._weight))))             # <<<<<<<<<<<<<<
@@ -7300,10 +7254,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 505, __pyx_L1_error)
+    __PYX_ERR(0, 510, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":504
+  /* "pywrapfst.pyx":509
  * cdef Weight _divide(Weight lhs, Weight rhs):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
@@ -7312,7 +7266,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Divide((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":506
+  /* "pywrapfst.pyx":511
  *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  *                                                       deref(rhs._weight))))
  *   return result             # <<<<<<<<<<<<<<
@@ -7324,7 +7278,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":502
+  /* "pywrapfst.pyx":507
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7344,7 +7298,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":509
+/* "pywrapfst.pyx":514
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7385,11 +7339,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, 509, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 514, __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, 509, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 514, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7402,14 +7356,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, 509, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 514, __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, 509, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 509, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_4divide(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7428,19 +7382,19 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("divide", 0);
 
-  /* "pywrapfst.pyx":531
+  /* "pywrapfst.pyx":536
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _divide(lhs, rhs)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 531, __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, 536, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":532
+  /* "pywrapfst.pyx":537
  *   """
  *   cdef Weight result = _divide(lhs, rhs)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7449,11 +7403,11 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 532, __pyx_L1_error)
+    __PYX_ERR(0, 537, __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, 532, __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)
 
-  /* "pywrapfst.pyx":533
+  /* "pywrapfst.pyx":538
  *   cdef Weight result = _divide(lhs, rhs)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7465,7 +7419,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":514
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7485,7 +7439,7 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":536
+/* "pywrapfst.pyx":541
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7500,19 +7454,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_power", 0);
 
-  /* "pywrapfst.pyx":537
+  /* "pywrapfst.pyx":542
  * 
  * 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
  */
-  __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, 537, __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, 542, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":538
+  /* "pywrapfst.pyx":543
  * 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)))             # <<<<<<<<<<<<<<
@@ -7521,15 +7475,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 538, __pyx_L1_error)
+    __PYX_ERR(0, 543, __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, 538, __pyx_L1_error)
+    __PYX_ERR(0, 543, __pyx_L1_error)
   }
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Power((*__pyx_v_w->_weight), __pyx_v_n)));
 
-  /* "pywrapfst.pyx":539
+  /* "pywrapfst.pyx":544
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  *   return result             # <<<<<<<<<<<<<<
@@ -7541,7 +7495,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":536
+  /* "pywrapfst.pyx":541
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7561,7 +7515,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":542
+/* "pywrapfst.pyx":547
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7602,11 +7556,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, 542, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 547, __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, 542, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 547, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7615,17 +7569,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, 542, __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, 547, __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, 542, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 547, __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, 542, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 547, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6power(__pyx_self, __pyx_v_w, __pyx_v_n);
 
   /* function exit code */
@@ -7644,19 +7598,19 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("power", 0);
 
-  /* "pywrapfst.pyx":559
+  /* "pywrapfst.pyx":564
  *     FstBadWeightError: Invalid weight.
  *   """
  *   cdef Weight result = _power(w, n)             # <<<<<<<<<<<<<<
  *   result._check_weight()
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __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, 564, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":560
+  /* "pywrapfst.pyx":565
  *   """
  *   cdef Weight result = _power(w, n)
  *   result._check_weight()             # <<<<<<<<<<<<<<
@@ -7665,11 +7619,11 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 560, __pyx_L1_error)
+    __PYX_ERR(0, 565, __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, 560, __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)
 
-  /* "pywrapfst.pyx":561
+  /* "pywrapfst.pyx":566
  *   cdef Weight result = _power(w, n)
  *   result._check_weight()
  *   return result             # <<<<<<<<<<<<<<
@@ -7681,7 +7635,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":547
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7701,7 +7655,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":564
+/* "pywrapfst.pyx":569
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7722,7 +7676,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_Zero", 0);
 
-  /* "pywrapfst.pyx":582
+  /* "pywrapfst.pyx":587
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7733,7 +7687,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":583
+    /* "pywrapfst.pyx":588
  *   cdef fst.WeightClass result
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)             # <<<<<<<<<<<<<<
@@ -7742,7 +7696,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  */
     __pyx_v_result = fst::script::WeightClass::Zero(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":582
+    /* "pywrapfst.pyx":587
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7752,7 +7706,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":584
+  /* "pywrapfst.pyx":589
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7763,7 +7717,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":585
+    /* "pywrapfst.pyx":590
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -7772,11 +7726,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 585, __pyx_L1_error)
+      __PYX_ERR(0, 590, __pyx_L1_error)
     }
     __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":584
+    /* "pywrapfst.pyx":589
  *   if weight is None:
  *     result = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7786,7 +7740,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":587
+  /* "pywrapfst.pyx":592
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
@@ -7794,10 +7748,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 587, __pyx_L1_error)
+    __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);
 
-    /* "pywrapfst.pyx":588
+    /* "pywrapfst.pyx":593
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():             # <<<<<<<<<<<<<<
@@ -7807,17 +7761,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
     __pyx_t_1 = ((!(__pyx_v_result.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":589
+      /* "pywrapfst.pyx":594
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 589, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 594, __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, 589, __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, 589, __pyx_L1_error)
+      __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_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -7832,14 +7786,14 @@ 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, 589, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __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, 589, __pyx_L1_error)
+      __PYX_ERR(0, 594, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":588
+      /* "pywrapfst.pyx":593
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():             # <<<<<<<<<<<<<<
@@ -7850,7 +7804,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":590
+  /* "pywrapfst.pyx":595
  *     if not result.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  *   return result             # <<<<<<<<<<<<<<
@@ -7860,7 +7814,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":564
+  /* "pywrapfst.pyx":569
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7881,7 +7835,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":593
+/* "pywrapfst.pyx":598
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7902,7 +7856,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_One", 0);
 
-  /* "pywrapfst.pyx":611
+  /* "pywrapfst.pyx":616
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7913,7 +7867,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":612
+    /* "pywrapfst.pyx":617
  *   cdef fst.WeightClass result
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)             # <<<<<<<<<<<<<<
@@ -7922,7 +7876,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  */
     __pyx_v_result = fst::script::WeightClass::One(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":611
+    /* "pywrapfst.pyx":616
  *   """
  *   cdef fst.WeightClass result
  *   if weight is None:             # <<<<<<<<<<<<<<
@@ -7932,7 +7886,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":613
+  /* "pywrapfst.pyx":618
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7943,7 +7897,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":614
+    /* "pywrapfst.pyx":619
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
@@ -7952,11 +7906,11 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 614, __pyx_L1_error)
+      __PYX_ERR(0, 619, __pyx_L1_error)
     }
     __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":613
+    /* "pywrapfst.pyx":618
  *   if weight is None:
  *     result = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
@@ -7966,7 +7920,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":616
+  /* "pywrapfst.pyx":621
  *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
@@ -7974,10 +7928,10 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 616, __pyx_L1_error)
+    __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);
 
-    /* "pywrapfst.pyx":617
+    /* "pywrapfst.pyx":622
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():             # <<<<<<<<<<<<<<
@@ -7987,17 +7941,17 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
     __pyx_t_1 = ((!(__pyx_v_result.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":618
+      /* "pywrapfst.pyx":623
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 618, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 623, __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, 618, __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, 618, __pyx_L1_error)
+      __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_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -8012,14 +7966,14 @@ 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, 618, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __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, 618, __pyx_L1_error)
+      __PYX_ERR(0, 623, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":617
+      /* "pywrapfst.pyx":622
  *   else:
  *     result = fst.WeightClass(weight_type, weight_tostring(weight))
  *     if not result.Member():             # <<<<<<<<<<<<<<
@@ -8030,7 +7984,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":619
+  /* "pywrapfst.pyx":624
  *     if not result.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  *   return result             # <<<<<<<<<<<<<<
@@ -8040,7 +7994,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":593
+  /* "pywrapfst.pyx":598
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8061,7 +8015,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":622
+/* "pywrapfst.pyx":627
  * 
  * 
  * cdef Weight _Zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8080,19 +8034,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_Zero", 0);
 
-  /* "pywrapfst.pyx":623
+  /* "pywrapfst.pyx":628
  * 
  * cdef Weight _Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._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, 623, __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, 628, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":624
+  /* "pywrapfst.pyx":629
  * cdef Weight _Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
@@ -8101,19 +8055,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 624, __pyx_L1_error)
+    __PYX_ERR(0, 629, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":625
+  /* "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":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 625, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 630, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":624
+  /* "pywrapfst.pyx":629
  * cdef Weight _Zero(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
@@ -8122,7 +8076,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::Zero(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":626
+  /* "pywrapfst.pyx":631
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8131,19 +8085,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 626, __pyx_L1_error)
+    __PYX_ERR(0, 631, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":627
+    /* "pywrapfst.pyx":632
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 627, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 632, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8157,14 +8111,14 @@ 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, 627, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __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, 627, __pyx_L1_error)
+    __PYX_ERR(0, 632, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":626
+    /* "pywrapfst.pyx":631
  *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
  *       tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8173,7 +8127,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
  */
   }
 
-  /* "pywrapfst.pyx":628
+  /* "pywrapfst.pyx":633
  *   if result._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  *   return result             # <<<<<<<<<<<<<<
@@ -8185,7 +8139,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":622
+  /* "pywrapfst.pyx":627
  * 
  * 
  * cdef Weight _Zero(weight_type):             # <<<<<<<<<<<<<<
@@ -8207,7 +8161,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":631
+/* "pywrapfst.pyx":636
  * 
  * 
  * cdef Weight _One(weight_type):             # <<<<<<<<<<<<<<
@@ -8226,19 +8180,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_One", 0);
 
-  /* "pywrapfst.pyx":632
+  /* "pywrapfst.pyx":637
  * 
  * cdef Weight _One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._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, 632, __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, 637, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":633
+  /* "pywrapfst.pyx":638
  * cdef Weight _One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8247,19 +8201,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 633, __pyx_L1_error)
+    __PYX_ERR(0, 638, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":634
+  /* "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":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 634, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 639, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":633
+  /* "pywrapfst.pyx":638
  * cdef Weight _One(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8268,7 +8222,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::One(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":635
+  /* "pywrapfst.pyx":640
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8277,19 +8231,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 635, __pyx_L1_error)
+    __PYX_ERR(0, 640, __pyx_L1_error)
   }
   __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":636
+    /* "pywrapfst.pyx":641
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 636, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 641, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8303,14 +8257,14 @@ 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, 636, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __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, 636, __pyx_L1_error)
+    __PYX_ERR(0, 641, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":635
+    /* "pywrapfst.pyx":640
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.One(tostring(weight_type))))
  *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
@@ -8319,7 +8273,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
  */
   }
 
-  /* "pywrapfst.pyx":637
+  /* "pywrapfst.pyx":642
  *   if result._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  *   return result             # <<<<<<<<<<<<<<
@@ -8331,7 +8285,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":631
+  /* "pywrapfst.pyx":636
  * 
  * 
  * cdef Weight _One(weight_type):             # <<<<<<<<<<<<<<
@@ -8353,7 +8307,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":640
+/* "pywrapfst.pyx":645
  * 
  * 
  * cdef Weight _NoWeight(weight_type):             # <<<<<<<<<<<<<<
@@ -8369,19 +8323,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
   std::string __pyx_t_2;
   __Pyx_RefNannySetupContext("_NoWeight", 0);
 
-  /* "pywrapfst.pyx":641
+  /* "pywrapfst.pyx":646
  * 
  * cdef Weight _NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
  *   result._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, 641, __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, 646, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":642
+  /* "pywrapfst.pyx":647
  * cdef Weight _NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8390,19 +8344,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 642, __pyx_L1_error)
+    __PYX_ERR(0, 647, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":643
+  /* "pywrapfst.pyx":648
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.NoWeight(tostring(weight_type))))             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 643, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 648, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":642
+  /* "pywrapfst.pyx":647
  * cdef Weight _NoWeight(weight_type):
  *   cdef Weight result = Weight.__new__(Weight)
  *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
@@ -8411,7 +8365,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
  */
   __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::NoWeight(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":644
+  /* "pywrapfst.pyx":649
  *   result._weight.reset(new fst.WeightClass(
  *         fst.WeightClass.NoWeight(tostring(weight_type))))
  *   return result             # <<<<<<<<<<<<<<
@@ -8423,7 +8377,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":640
+  /* "pywrapfst.pyx":645
  * 
  * 
  * cdef Weight _NoWeight(weight_type):             # <<<<<<<<<<<<<<
@@ -8443,7 +8397,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":678
+/* "pywrapfst.pyx":683
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8478,28 +8432,28 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":679
+  /* "pywrapfst.pyx":684
  * 
  *   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, 679, __pyx_L1_error)
+  __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":680
+  /* "pywrapfst.pyx":685
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(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, 680, __pyx_L1_error)
+  __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, 680, __pyx_L1_error)
+  __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, 680, __pyx_L1_error)
+  __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;
@@ -8515,7 +8469,7 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   __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, 680, __pyx_L1_error)
+  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;
@@ -8531,14 +8485,14 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   __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, 679, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __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, 679, __pyx_L1_error)
+  __PYX_ERR(0, 684, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":678
+  /* "pywrapfst.pyx":683
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -8560,11 +8514,11 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":682
+/* "pywrapfst.pyx":687
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
- *     return SymbolTableIterator(self)
+ *     return _SymbolTableIterator(self)
  * 
  */
 
@@ -8587,25 +8541,25 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":683
+  /* "pywrapfst.pyx":688
  * 
  *   def __iter__(self):
- *     return SymbolTableIterator(self)             # <<<<<<<<<<<<<<
+ *     return _SymbolTableIterator(self)             # <<<<<<<<<<<<<<
  * 
  *   # 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, 683, __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, 688, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":682
+  /* "pywrapfst.pyx":687
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
- *     return SymbolTableIterator(self)
+ *     return _SymbolTableIterator(self)
  * 
  */
 
@@ -8620,7 +8574,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":687
+/* "pywrapfst.pyx":692
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8649,28 +8603,28 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":688
+  /* "pywrapfst.pyx":693
  * 
  *   def __reduce__(self):
  *     return (_read_SymbolTable_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
  * 
- *   cpdef int64 available_key(self):
+ *   # 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, 688, __pyx_L1_error)
+  __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_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, 688, __pyx_L1_error)
+    __PYX_ERR(0, 693, __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, 688, __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_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 688, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 693, __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, 688, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -8682,7 +8636,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":687
+  /* "pywrapfst.pyx":692
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8703,23 +8657,208 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":690
- *     return (_read_SymbolTable_from_string, (self.write_to_string(),))
+/* "pywrapfst.pyx":699
+ *   # 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):             # <<<<<<<<<<<<<<
+ *     return NULL
  * 
- *   cpdef int64 available_key(self):             # <<<<<<<<<<<<<<
+ */
+
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTable__raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_raw", 0);
+
+  /* "pywrapfst.pyx":700
+ *   # All other methods should use the safer _raw_ptr_or_raise() instead.
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return NULL             # <<<<<<<<<<<<<<
+ * 
+ *   # Raises an FstOpError for a nonexistent SymbolTable.
+ */
+  __pyx_r = NULL;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":699
+ *   # 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):             # <<<<<<<<<<<<<<
+ *     return NULL
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":703
+ * 
+ *   # Raises an FstOpError for a nonexistent SymbolTable.
+ *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
+ *     raise FstOpError("SymbolTable no longer exists")
+ * 
+ */
+
+static void __pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannySetupContext("_raise_nonexistent", 0);
+
+  /* "pywrapfst.pyx":704
+ *   # 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_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __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_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  __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)
+  __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)
+
+  /* "pywrapfst.pyx":703
+ * 
+ *   # Raises an FstOpError for a nonexistent SymbolTable.
+ *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
+ *     raise FstOpError("SymbolTable no longer exists")
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __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_RefNannyFinishContext();
+}
+
+/* "pywrapfst.pyx":708
+ *   # 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:
+ */
+
+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;
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_raw_ptr_or_raise", 0);
+
+  /* "pywrapfst.pyx":709
+ *   # fst.SymbolTable is required.
+ *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
+ *     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_v_raw = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw(__pyx_v_self);
+
+  /* "pywrapfst.pyx":710
+ *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
+ *     cdef const_SymbolTable_ptr raw = self._raw()
+ *     if raw == NULL:             # <<<<<<<<<<<<<<
+ *       self._raise_nonexistent()
+ *     return raw
+ */
+  __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:
+ *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
+ *     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)
+    }
+    ((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)
+
+    /* "pywrapfst.pyx":710
+ *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
+ *     cdef const_SymbolTable_ptr raw = self._raw()
+ *     if raw == NULL:             # <<<<<<<<<<<<<<
+ *       self._raise_nonexistent()
+ *     return raw
+ */
+  }
+
+  /* "pywrapfst.pyx":712
+ *     if raw == NULL:
+ *       self._raise_nonexistent()
+ *     return raw             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef int64 available_key(self) except *:
+ */
+  __pyx_r = __pyx_v_raw;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":708
+ *   # 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:
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("pywrapfst._SymbolTable._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
+ * 
+ *   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 __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_r;
+static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
+  int64 __pyx_t_5;
+  fst::SymbolTable const *__pyx_t_6;
   __Pyx_RefNannySetupContext("available_key", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -8730,7 +8869,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
     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, 690, __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, 714, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -8746,10 +8885,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
         }
         __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, 690, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 690, __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, 714, __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;
@@ -8768,24 +8907,25 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
     #endif
   }
 
-  /* "pywrapfst.pyx":696
+  /* "pywrapfst.pyx":720
  *     Returns an integer indicating the next available key index in the table.
  *     """
- *     return self._table.AvailableKey()             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().AvailableKey()             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes checksum(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 696, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 720, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_table->AvailableKey();
+  __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_r = __pyx_t_6->AvailableKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":690
- *     return (_read_SymbolTable_from_string, (self.write_to_string(),))
+  /* "pywrapfst.pyx":714
+ *     return raw
  * 
- *   cpdef int64 available_key(self):             # <<<<<<<<<<<<<<
+ *   cpdef int64 available_key(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     available_key(self)
  */
@@ -8796,7 +8936,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_available_ke
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._SymbolTable.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._SymbolTable.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -8820,18 +8960,20 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7available_key(PyObject *__p
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  int64 __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("available_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_12_SymbolTable_available_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 690, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __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_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -8840,8 +8982,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":698
- *     return self._table.AvailableKey()
+/* "pywrapfst.pyx":722
+ *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
  *     """
@@ -8856,6 +8998,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  fst::SymbolTable const *__pyx_t_5;
   __Pyx_RefNannySetupContext("checksum", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -8866,7 +9009,7 @@ 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, 698, __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, 722, __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)) {
         __Pyx_XDECREF(__pyx_r);
@@ -8883,10 +9026,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, 698, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 722, __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, 698, __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, 722, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -8905,26 +9048,27 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
     #endif
   }
 
-  /* "pywrapfst.pyx":704
+  /* "pywrapfst.pyx":728
  *     Returns a bytestring indicating the label-independent MD5 checksum.
  *     """
- *     return self._table.CheckSum()             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().CheckSum()             # <<<<<<<<<<<<<<
  * 
  *   cpdef SymbolTable copy(self):
  */
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 704, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 728, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_self->_table->CheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __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_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":698
- *     return self._table.AvailableKey()
+  /* "pywrapfst.pyx":722
+ *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
  *     """
@@ -8965,7 +9109,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __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, 698, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -8982,8 +9126,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":706
- *     return self._table.CheckSum()
+/* "pywrapfst.pyx":730
+ *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -8998,6 +9142,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  fst::SymbolTable const *__pyx_t_5;
   __Pyx_RefNannySetupContext("copy", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9008,7 +9153,7 @@ 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, 706, __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, 730, __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)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -9025,10 +9170,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, 706, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 730, __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, 706, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 730, __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;
@@ -9047,26 +9192,27 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
     #endif
   }
 
-  /* "pywrapfst.pyx":712
+  /* "pywrapfst.pyx":736
  *     Returns a mutable copy of the SymbolTable.
  *     """
- *     return _init_SymbolTable(self._table.Copy())             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))             # <<<<<<<<<<<<<<
  * 
  *   def find(self, key):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 712, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 736, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_self->_table->Copy())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 712, __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_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":706
- *     return self._table.CheckSum()
+  /* "pywrapfst.pyx":730
+ *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
  *     """
@@ -9107,7 +9253,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 706, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9124,8 +9270,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":714
- *     return _init_SymbolTable(self._table.Copy())
+/* "pywrapfst.pyx":738
+ *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
  *     """
@@ -9147,140 +9293,148 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13find(PyObject *__pyx_v_sel
 }
 
 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;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  fst::SymbolTable const *__pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
-  std::string __pyx_t_4;
-  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  std::string __pyx_t_5;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
-  int __pyx_t_9;
-  __pyx_t_10basictypes_int64 __pyx_t_10;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_t_10;
+  int64 __pyx_t_11;
   __Pyx_RefNannySetupContext("find", 0);
 
-  /* "pywrapfst.pyx":731
+  /* "pywrapfst.pyx":755
  *           not found.
  *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     try:
+ *       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_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;
+
+  /* "pywrapfst.pyx":756
+ *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.FindIndex(tostring(key))
+ *       return raw.FindIndex(tostring(key))
  *     except FstArgError:
  */
   {
     __Pyx_PyThreadState_declare
     __Pyx_PyThreadState_assign
-    __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
-    __Pyx_XGOTREF(__pyx_t_1);
+    __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
     __Pyx_XGOTREF(__pyx_t_2);
     __Pyx_XGOTREF(__pyx_t_3);
+    __Pyx_XGOTREF(__pyx_t_4);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":732
- *     """
+      /* "pywrapfst.pyx":757
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:
- *       return self._table.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
+ *       return raw.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
  *     except FstArgError:
- *       return self._table.FindSymbol(key)
+ *       return raw.FindSymbol(key)
  */
       __Pyx_XDECREF(__pyx_r);
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-        __PYX_ERR(0, 732, __pyx_L3_error)
-      }
-      __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 732, __pyx_L3_error)
-      __pyx_t_5 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_table->Find(__pyx_t_4)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 732, __pyx_L3_error)
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_r = __pyx_t_5;
-      __pyx_t_5 = 0;
+      __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_GOTREF(__pyx_t_6);
+      __pyx_r = __pyx_t_6;
+      __pyx_t_6 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":731
- *           not found.
+      /* "pywrapfst.pyx":756
  *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.FindIndex(tostring(key))
+ *       return raw.FindIndex(tostring(key))
  *     except FstArgError:
  */
     }
     __pyx_L3_error:;
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":733
+    /* "pywrapfst.pyx":758
  *     try:
- *       return self._table.FindIndex(tostring(key))
+ *       return raw.FindIndex(tostring(key))
  *     except FstArgError:             # <<<<<<<<<<<<<<
- *       return self._table.FindSymbol(key)
+ *       return raw.FindSymbol(key)
  * 
  */
-    __Pyx_ErrFetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7);
-    __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 733, __pyx_L5_except_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    __pyx_t_9 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_5, __pyx_t_8);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-    __Pyx_ErrRestore(__pyx_t_5, __pyx_t_6, __pyx_t_7);
-    __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0;
-    if (__pyx_t_9) {
+    __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_7, &__pyx_t_6, &__pyx_t_5) < 0) __PYX_ERR(0, 733, __pyx_L5_except_error)
+      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_GOTREF(__pyx_t_6);
-      __Pyx_GOTREF(__pyx_t_5);
 
-      /* "pywrapfst.pyx":734
- *       return self._table.FindIndex(tostring(key))
+      /* "pywrapfst.pyx":759
+ *       return raw.FindIndex(tostring(key))
  *     except FstArgError:
- *       return self._table.FindSymbol(key)             # <<<<<<<<<<<<<<
+ *       return raw.FindSymbol(key)             # <<<<<<<<<<<<<<
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:
  */
       __Pyx_XDECREF(__pyx_r);
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-        __PYX_ERR(0, 734, __pyx_L5_except_error)
-      }
-      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 734, __pyx_L5_except_error)
-      __pyx_t_8 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_self->_table->Find(__pyx_t_10)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 734, __pyx_L5_except_error)
-      __Pyx_GOTREF(__pyx_t_8);
-      __pyx_r = __pyx_t_8;
-      __pyx_t_8 = 0;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __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_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;
       goto __pyx_L6_except_return;
     }
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":731
- *           not found.
+    /* "pywrapfst.pyx":756
  *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.FindIndex(tostring(key))
+ *       return raw.FindIndex(tostring(key))
  *     except FstArgError:
  */
-    __Pyx_XGIVEREF(__pyx_t_1);
     __Pyx_XGIVEREF(__pyx_t_2);
     __Pyx_XGIVEREF(__pyx_t_3);
-    __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
     goto __pyx_L1_error;
     __pyx_L7_try_return:;
-    __Pyx_XGIVEREF(__pyx_t_1);
     __Pyx_XGIVEREF(__pyx_t_2);
     __Pyx_XGIVEREF(__pyx_t_3);
-    __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
     goto __pyx_L0;
     __pyx_L6_except_return:;
-    __Pyx_XGIVEREF(__pyx_t_1);
     __Pyx_XGIVEREF(__pyx_t_2);
     __Pyx_XGIVEREF(__pyx_t_3);
-    __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":714
- *     return _init_SymbolTable(self._table.Copy())
+  /* "pywrapfst.pyx":738
+ *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
  *     """
@@ -9289,10 +9443,10 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
 
   /* function exit code */
   __pyx_L1_error:;
-  __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._SymbolTable.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -9301,8 +9455,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":736
- *       return self._table.FindSymbol(key)
+/* "pywrapfst.pyx":761
+ *       return raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -9310,15 +9464,16 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
-static __pyx_t_10basictypes_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) {
-  __pyx_t_10basictypes_int64 __pyx_r;
+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) {
+  int64 __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;
-  __pyx_t_10basictypes_int64 __pyx_t_6;
+  int64 __pyx_t_6;
+  fst::SymbolTable const *__pyx_t_7;
   __Pyx_RefNannySetupContext("get_nth_key", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9329,10 +9484,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
     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, 736, __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, 761, __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, 736, __pyx_L1_error)
+        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 761, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -9348,10 +9503,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
         __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, 736, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 736, __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, 761, __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;
@@ -9370,22 +9525,23 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(
     #endif
   }
 
-  /* "pywrapfst.pyx":748
+  /* "pywrapfst.pyx":773
  *       The integer index of the n-th key, or NO_LABEL if not found.
  *     """
- *     return self._table.GetNthKey(pos)             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().GetNthKey(pos)             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes labeled_checksum(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 748, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 773, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_table->GetNthKey(__pyx_v_pos);
+  __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_r = __pyx_t_7->GetNthKey(__pyx_v_pos);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":736
- *       return self._table.FindSymbol(key)
+  /* "pywrapfst.pyx":761
+ *       return raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -9415,7 +9571,7 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__py
   __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, 736, __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, 761, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -9433,12 +9589,12 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__py
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __pyx_t_10basictypes_int64 __pyx_t_1;
+  int64 __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __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, 736, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 736, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9455,8 +9611,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":750
- *     return self._table.GetNthKey(pos)
+/* "pywrapfst.pyx":775
+ *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
  *     """
@@ -9471,6 +9627,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  fst::SymbolTable const *__pyx_t_5;
   __Pyx_RefNannySetupContext("labeled_checksum", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9481,7 +9638,7 @@ 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, 750, __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, 775, __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)) {
         __Pyx_XDECREF(__pyx_r);
@@ -9498,10 +9655,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, 750, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __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, 750, __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, 775, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9520,26 +9677,27 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
     #endif
   }
 
-  /* "pywrapfst.pyx":756
+  /* "pywrapfst.pyx":781
  *     Returns a bytestring indicating the label-dependent MD5 checksum.
  *     """
- *     return self._table.LabeledCheckSum()             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().LabeledCheckSum()             # <<<<<<<<<<<<<<
  * 
- *   cpdef bool member(self, key):
+ *   cpdef bool member(self, key) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 756, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 781, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_self->_table->LabeledCheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __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_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":750
- *     return self._table.GetNthKey(pos)
+  /* "pywrapfst.pyx":775
+ *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
  *     """
@@ -9580,7 +9738,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __
   PyObject *__pyx_t_1 = NULL;
   __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, 750, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9597,16 +9755,17 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":758
- *     return self._table.LabeledCheckSum()
+/* "pywrapfst.pyx":783
+ *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
- *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
+ *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
  *     """
  *     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;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -9614,12 +9773,13 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
+  fst::SymbolTable const *__pyx_t_6;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
-  std::string __pyx_t_9;
-  int __pyx_t_10;
-  __pyx_t_10basictypes_int64 __pyx_t_11;
+  PyObject *__pyx_t_9 = NULL;
+  std::string __pyx_t_10;
+  int __pyx_t_11;
+  int64 __pyx_t_12;
   __Pyx_RefNannySetupContext("member", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9630,7 +9790,7 @@ 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, 758, __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, 783, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -9646,10 +9806,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, 758, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __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, 758, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9668,42 +9828,52 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":774
+  /* "pywrapfst.pyx":799
  *       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()             # <<<<<<<<<<<<<<
+ *     try:
+ *       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_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;
+
+  /* "pywrapfst.pyx":800
+ *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
+ *       return raw.MemberSymbol(tostring(key))
  *     except FstArgError:
  */
   {
     __Pyx_PyThreadState_declare
     __Pyx_PyThreadState_assign
-    __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
-    __Pyx_XGOTREF(__pyx_t_6);
+    __Pyx_ExceptionSave(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
     __Pyx_XGOTREF(__pyx_t_7);
     __Pyx_XGOTREF(__pyx_t_8);
+    __Pyx_XGOTREF(__pyx_t_9);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":775
- *     """
+      /* "pywrapfst.pyx":801
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:
- *       return self._table.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
+ *       return raw.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
  *     except FstArgError:
- *       return self._table.MemberIndex(key)
+ *       return raw.MemberIndex(key)
  */
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-        __PYX_ERR(0, 775, __pyx_L3_error)
-      }
-      __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 775, __pyx_L3_error)
-      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_9);
+      __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);
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":774
- *       Whether or not the key is present (as a string or a index) in the table.
+      /* "pywrapfst.pyx":800
  *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
+ *       return raw.MemberSymbol(tostring(key))
  *     except FstArgError:
  */
     }
@@ -9713,40 +9883,36 @@ 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":776
+    /* "pywrapfst.pyx":802
  *     try:
- *       return self._table.MemberSymbol(tostring(key))
+ *       return raw.MemberSymbol(tostring(key))
  *     except FstArgError:             # <<<<<<<<<<<<<<
- *       return self._table.MemberIndex(key)
+ *       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, 776, __pyx_L5_except_error)
+    __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_10 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __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;
-    if (__pyx_t_10) {
+    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, 776, __pyx_L5_except_error)
+      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_GOTREF(__pyx_t_1);
 
-      /* "pywrapfst.pyx":777
- *       return self._table.MemberSymbol(tostring(key))
+      /* "pywrapfst.pyx":803
+ *       return raw.MemberSymbol(tostring(key))
  *     except FstArgError:
- *       return self._table.MemberIndex(key)             # <<<<<<<<<<<<<<
+ *       return raw.MemberIndex(key)             # <<<<<<<<<<<<<<
  * 
  *   def __contains__(self, key):
  */
-      if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-        __PYX_ERR(0, 777, __pyx_L5_except_error)
-      }
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 777, __pyx_L5_except_error)
-      __pyx_r = __pyx_v_self->_table->Member(__pyx_t_11);
+      __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_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;
@@ -9755,36 +9921,36 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":774
- *       Whether or not the key is present (as a string or a index) in the table.
+    /* "pywrapfst.pyx":800
  *     """
+ *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return self._table.MemberSymbol(tostring(key))
+ *       return raw.MemberSymbol(tostring(key))
  *     except FstArgError:
  */
-    __Pyx_XGIVEREF(__pyx_t_6);
     __Pyx_XGIVEREF(__pyx_t_7);
     __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
     goto __pyx_L1_error;
     __pyx_L7_try_return:;
-    __Pyx_XGIVEREF(__pyx_t_6);
     __Pyx_XGIVEREF(__pyx_t_7);
     __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
     goto __pyx_L0;
     __pyx_L6_except_return:;
-    __Pyx_XGIVEREF(__pyx_t_6);
     __Pyx_XGIVEREF(__pyx_t_7);
     __Pyx_XGIVEREF(__pyx_t_8);
-    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+    __Pyx_XGIVEREF(__pyx_t_9);
+    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":758
- *     return self._table.LabeledCheckSum()
+  /* "pywrapfst.pyx":783
+ *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
- *   cpdef bool member(self, key):             # <<<<<<<<<<<<<<
+ *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
  *     """
  *     member(self, key)
  */
@@ -9795,7 +9961,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_WriteUnraisable("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -9819,18 +9985,20 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19member(PyObject *__pyx_v_s
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  bool __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("member", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_12_SymbolTable_member(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 758, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __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_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -9839,8 +10007,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":779
- *       return self._table.MemberIndex(key)
+/* "pywrapfst.pyx":805
+ *       return raw.MemberIndex(key)
  * 
  *   def __contains__(self, key):             # <<<<<<<<<<<<<<
  *     return self.member(key)
@@ -9863,24 +10031,26 @@ static int __pyx_pw_9pywrapfst_12_SymbolTable_21__contains__(PyObject *__pyx_v_s
 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":780
+  /* "pywrapfst.pyx":806
  * 
  *   def __contains__(self, key):
  *     return self.member(key)             # <<<<<<<<<<<<<<
  * 
- *   cpdef string name(self):
+ *   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, 780, __pyx_L1_error)
+    __PYX_ERR(0, 806, __pyx_L1_error)
   }
-  __pyx_r = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, __pyx_v_key, 0);
+  __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":779
- *       return self._table.MemberIndex(key)
+  /* "pywrapfst.pyx":805
+ *       return raw.MemberIndex(key)
  * 
  *   def __contains__(self, key):             # <<<<<<<<<<<<<<
  *     return self.member(key)
@@ -9896,10 +10066,10 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable_20__contains__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":782
+/* "pywrapfst.pyx":808
  *     return self.member(key)
  * 
- *   cpdef string name(self):             # <<<<<<<<<<<<<<
+ *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     name(self)
  */
@@ -9913,6 +10083,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  fst::SymbolTable const *__pyx_t_6;
   __Pyx_RefNannySetupContext("name", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9923,7 +10094,7 @@ 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, 782, __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, 808, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -9939,10 +10110,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, 782, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __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, 782, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9961,24 +10132,25 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":788
+  /* "pywrapfst.pyx":814
  *     Returns the symbol table's name.
  *     """
- *     return self._table.Name()             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().Name()             # <<<<<<<<<<<<<<
  * 
- *   cpdef size_t num_symbols(self):
+ *   cpdef size_t num_symbols(self) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 788, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 814, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_table->Name();
+  __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_r = __pyx_t_6->Name();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":782
+  /* "pywrapfst.pyx":808
  *     return self.member(key)
  * 
- *   cpdef string name(self):             # <<<<<<<<<<<<<<
+ *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     name(self)
  */
@@ -9989,7 +10161,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_WriteUnraisable("pywrapfst._SymbolTable.name", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._SymbolTable.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10013,18 +10185,20 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23name(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  std::string __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12_SymbolTable_name(__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;
+  __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_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -10033,10 +10207,10 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":790
- *     return self._table.Name()
+/* "pywrapfst.pyx":816
+ *     return self._raw_ptr_or_raise().Name()
  * 
- *   cpdef size_t num_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     num_symbols(self)
  */
@@ -10050,6 +10224,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   size_t __pyx_t_5;
+  fst::SymbolTable const *__pyx_t_6;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10060,7 +10235,7 @@ 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, 790, __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, 816, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10076,10 +10251,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, 790, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __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, 790, __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, 816, __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;
@@ -10098,24 +10273,25 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
     #endif
   }
 
-  /* "pywrapfst.pyx":796
+  /* "pywrapfst.pyx":822
  *     Returns the number of symbols in the symbol table.
  *     """
- *     return self._table.NumSymbols()             # <<<<<<<<<<<<<<
+ *     return self._raw_ptr_or_raise().NumSymbols()             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write(self, source) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 796, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 822, __pyx_L1_error)
   }
-  __pyx_r = __pyx_v_self->_table->NumSymbols();
+  __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_r = __pyx_t_6->NumSymbols();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":790
- *     return self._table.Name()
+  /* "pywrapfst.pyx":816
+ *     return self._raw_ptr_or_raise().Name()
  * 
- *   cpdef size_t num_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     num_symbols(self)
  */
@@ -10126,7 +10302,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_WriteUnraisable("pywrapfst._SymbolTable.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._SymbolTable.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10150,18 +10326,20 @@ static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols(PyObject *__py
 static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  size_t __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_12_SymbolTable_num_symbols(__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;
+  __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_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -10170,8 +10348,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":798
- *     return self._table.NumSymbols()
+/* "pywrapfst.pyx":824
+ *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -10185,9 +10363,10 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  fst::SymbolTable const *__pyx_t_5;
+  std::string __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10198,7 +10377,7 @@ 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, 798, __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, 824, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10214,7 +10393,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, 798, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 824, __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;
@@ -10234,45 +10413,46 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":812
+  /* "pywrapfst.pyx":838
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().Write(tostring(source)):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 812, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 838, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 812, __pyx_L1_error)
-  __pyx_t_6 = ((!(__pyx_v_self->_table->Write(__pyx_t_5) != 0)) != 0);
-  if (unlikely(__pyx_t_6)) {
+  __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_7 = ((!(__pyx_t_5->Write(__pyx_t_6) != 0)) != 0);
+  if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":813
+    /* "pywrapfst.pyx":839
  *     """
- *     if not self._table.Write(tostring(source)):
+ *     if not self._raw_ptr_or_raise().Write(tostring(source)):
  *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write_text(self, source) except *:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 813, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 839, __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, 813, __pyx_L1_error)
+    __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_7 = NULL;
+    __pyx_t_8 = 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)) {
+      __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_7);
+        __Pyx_INCREF(__pyx_t_8);
         __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, 813, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -10288,24 +10468,24 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     __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, 813, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 839, __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, 813, __pyx_L1_error)
+    __PYX_ERR(0, 839, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":812
+    /* "pywrapfst.pyx":838
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.Write(tostring(source)):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().Write(tostring(source)):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   }
 
-  /* "pywrapfst.pyx":798
- *     return self._table.NumSymbols()
+  /* "pywrapfst.pyx":824
+ *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -10319,7 +10499,7 @@ 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_7);
+  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10345,8 +10525,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __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, 798, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 798, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10363,7 +10543,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":815
+/* "pywrapfst.pyx":841
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10378,9 +10558,10 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  fst::SymbolTable const *__pyx_t_5;
+  std::string __pyx_t_6;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("write_text", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10391,7 +10572,7 @@ 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, 815, __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, 841, __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)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -10407,7 +10588,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, 815, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __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;
@@ -10427,45 +10608,46 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":829
+  /* "pywrapfst.pyx":855
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.WriteText(tostring(source)):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 829, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 855, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 829, __pyx_L1_error)
-  __pyx_t_6 = ((!(__pyx_v_self->_table->WriteText(__pyx_t_5) != 0)) != 0);
-  if (unlikely(__pyx_t_6)) {
+  __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_7 = ((!(__pyx_t_5->WriteText(__pyx_t_6) != 0)) != 0);
+  if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":830
+    /* "pywrapfst.pyx":856
  *     """
- *     if not self._table.WriteText(tostring(source)):
+ *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):
  *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 830, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 856, __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, 830, __pyx_L1_error)
+    __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_7 = NULL;
+    __pyx_t_8 = 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)) {
+      __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_7);
+        __Pyx_INCREF(__pyx_t_8);
         __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, 830, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -10481,23 +10663,23 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     __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, 830, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 856, __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, 830, __pyx_L1_error)
+    __PYX_ERR(0, 856, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":829
+    /* "pywrapfst.pyx":855
  *       FstIOError: Write failed.
  *     """
- *     if not self._table.WriteText(tostring(source)):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  */
   }
 
-  /* "pywrapfst.pyx":815
+  /* "pywrapfst.pyx":841
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10512,7 +10694,7 @@ 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_7);
+  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst._SymbolTable.write_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10538,8 +10720,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 815, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 815, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10556,7 +10738,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":832
+/* "pywrapfst.pyx":858
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -10573,7 +10755,8 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
+  fst::SymbolTable const *__pyx_t_5;
+  int __pyx_t_6;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10584,7 +10767,7 @@ 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, 832, __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, 858, __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)) {
         __Pyx_XDECREF(__pyx_r);
@@ -10601,10 +10784,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, 832, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 858, __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, 832, __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, 858, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10623,28 +10806,29 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":845
+  /* "pywrapfst.pyx":871
  *     """
  *     cdef stringstream sstrm
- *     if not self._table.Write(sstrm):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().Write(sstrm):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
  *     return sstrm.str()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 845, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 871, __pyx_L1_error)
   }
-  __pyx_t_5 = ((!(__pyx_v_self->_table->Write(__pyx_v_sstrm) != 0)) != 0);
-  if (unlikely(__pyx_t_5)) {
+  __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);
+  if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":846
+    /* "pywrapfst.pyx":872
  *     cdef stringstream sstrm
- *     if not self._table.Write(sstrm):
+ *     if not self._raw_ptr_or_raise().Write(sstrm):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 846, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 872, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -10658,37 +10842,37 @@ 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, 846, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 872, __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, 846, __pyx_L1_error)
+    __PYX_ERR(0, 872, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":845
+    /* "pywrapfst.pyx":871
  *     """
  *     cdef stringstream sstrm
- *     if not self._table.Write(sstrm):             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().Write(sstrm):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
  *     return sstrm.str()
  */
   }
 
-  /* "pywrapfst.pyx":847
- *     if not self._table.Write(sstrm):
+  /* "pywrapfst.pyx":873
+ *     if not self._raw_ptr_or_raise().Write(sstrm):
  *       raise FstIOError("Write to string failed")
  *     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, 847, __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, 873, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":832
+  /* "pywrapfst.pyx":858
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -10730,7 +10914,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __p
   PyObject *__pyx_t_1 = NULL;
   __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, 832, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10747,135 +10931,137 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":865
+/* "pywrapfst.pyx":891
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                                     id(self))
+ *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
+ *       self.name(), id(self))
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_24_EncodeMapperSymbolTable_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_24_EncodeMapperSymbolTable_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_28_EncodeMapperSymbolTableView_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_28_EncodeMapperSymbolTableView_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":866
+  /* "pywrapfst.pyx":892
  * 
  *   def __repr__(self):
- *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
- *                                                                     id(self))
+ *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(             # <<<<<<<<<<<<<<
+ *       self.name(), id(self))
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_EncodeMapper_SymbolTable, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error)
+  __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);
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 866, __pyx_L1_error)
-  }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 866, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
 
-  /* "pywrapfst.pyx":867
+  /* "pywrapfst.pyx":893
  *   def __repr__(self):
- *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                                     id(self))             # <<<<<<<<<<<<<<
- * 
+ *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
+ *       self.name(), id(self))             # <<<<<<<<<<<<<<
  * 
+ *   cdef const_SymbolTable_ptr _raw(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 867, __pyx_L1_error)
+  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 = NULL;
-  __pyx_t_6 = 0;
+  __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_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 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)) {
+    __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_5);
+      __Pyx_INCREF(__pyx_t_6);
       __Pyx_INCREF(function);
       __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
+      __pyx_t_7 = 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, 866, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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[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, 866, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 866, __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_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_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;
+    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_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 866, __pyx_L1_error)
+    __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_7); __pyx_t_7 = 0;
+    __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":865
+  /* "pywrapfst.pyx":891
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                                     id(self))
+ *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
+ *       self.name(), id(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_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_AddTraceback("pywrapfst._EncodeMapperSymbolTable.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10883,135 +11069,203 @@ static PyObject *__pyx_pf_9pywrapfst_24_EncodeMapperSymbolTable___repr__(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":884
+/* "pywrapfst.pyx":895
+ *       self.name(), id(self))
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._mapper.get().InputSymbols() if self._input_side
+ *             else self._mapper.get().OutputSymbols())
+ */
+
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapperSymbolTableView__raw(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v_self) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  fst::SymbolTable const *__pyx_t_1;
+  __Pyx_RefNannySetupContext("_raw", 0);
+
+  /* "pywrapfst.pyx":896
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return (self._mapper.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
+ *             else self._mapper.get().OutputSymbols())
+ * 
+ */
+  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)
+  }
+  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_t_1 = __pyx_v_self->_mapper.get()->InputSymbols();
+  } else {
+
+    /* "pywrapfst.pyx":897
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return (self._mapper.get().InputSymbols() if self._input_side
+ *             else self._mapper.get().OutputSymbols())             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    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_t_1 = __pyx_v_self->_mapper.get()->OutputSymbols();
+  }
+  __pyx_r = __pyx_t_1;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":895
+ *       self.name(), id(self))
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._mapper.get().InputSymbols() if self._input_side
+ *             else self._mapper.get().OutputSymbols())
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_WriteUnraisable("pywrapfst._EncodeMapperSymbolTableView._raw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":914
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                            id(self))
+ *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
+ *                                                                id(self))
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_15_FstSymbolTable_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_15_FstSymbolTable_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_19_FstSymbolTableView_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_FstSymbolTableView_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":885
+  /* "pywrapfst.pyx":915
  * 
  *   def __repr__(self):
- *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
- *                                                            id(self))
+ *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
+ *                                                                id(self))
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 885, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 885, __pyx_L1_error)
+    __PYX_ERR(0, 915, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 885, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
+  __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);
 
-  /* "pywrapfst.pyx":886
+  /* "pywrapfst.pyx":916
  *   def __repr__(self):
- *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                            id(self))             # <<<<<<<<<<<<<<
- * 
+ *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
+ *                                                                id(self))             # <<<<<<<<<<<<<<
  * 
+ *   cdef const_SymbolTable_ptr _raw(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 886, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = NULL;
-  __pyx_t_6 = 0;
+  __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_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 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)) {
+    __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_5);
+      __Pyx_INCREF(__pyx_t_6);
       __Pyx_INCREF(function);
       __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
+      __pyx_t_7 = 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, 885, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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[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, 885, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 885, __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_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_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;
+    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_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 885, __pyx_L1_error)
+    __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_7); __pyx_t_7 = 0;
+    __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":884
+  /* "pywrapfst.pyx":914
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
- *                                                            id(self))
+ *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
+ *                                                                id(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_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_AddTraceback("pywrapfst._FstSymbolTable.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -11019,19 +11273,254 @@ static PyObject *__pyx_pf_9pywrapfst_15_FstSymbolTable___repr__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":900
+/* "pywrapfst.pyx":918
+ *                                                                id(self))
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._fst.get().InputSymbols() if self._input_side
+ *             else self._fst.get().OutputSymbols())
+ */
+
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolTableView__raw(struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v_self) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  fst::SymbolTable const *__pyx_t_1;
+  __Pyx_RefNannySetupContext("_raw", 0);
+
+  /* "pywrapfst.pyx":919
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return (self._fst.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
+ *             else self._fst.get().OutputSymbols())
+ * 
+ */
+  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)
+  }
+  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_t_1 = __pyx_v_self->_fst.get()->InputSymbols();
+  } else {
+
+    /* "pywrapfst.pyx":920
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return (self._fst.get().InputSymbols() if self._input_side
+ *             else 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, 920, __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))
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._fst.get().InputSymbols() if self._input_side
+ *             else self._fst.get().OutputSymbols())
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_WriteUnraisable("pywrapfst._FstSymbolTableView._raw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":934
  *   """
  * 
- *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return self._mutable_raw()
+ * 
+ */
+
+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
+  __Pyx_RefNannySetupContext("_raw", 0);
+
+  /* "pywrapfst.pyx":935
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):
+ *     return self._mutable_raw()             # <<<<<<<<<<<<<<
+ * 
+ *   # Returns a mutable raw pointer to SymbolTable.
+ */
+  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_r = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":934
+ *   """
+ * 
+ *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
+ *     return self._mutable_raw()
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_WriteUnraisable("pywrapfst._MutableSymbolTable._raw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":941
+ *   # 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):             # <<<<<<<<<<<<<<
+ *     return NULL
+ * 
+ */
+
+static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self) {
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_mutable_raw", 0);
+
+  /* "pywrapfst.pyx":942
+ *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
+ *   cdef SymbolTable_ptr _mutable_raw(self):
+ *     return NULL             # <<<<<<<<<<<<<<
+ * 
+ *   # Internal API method that should be used when a mutable pointer to an
+ */
+  __pyx_r = NULL;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":941
+ *   # 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):             # <<<<<<<<<<<<<<
+ *     return NULL
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":946
+ *   # 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 *:             # <<<<<<<<<<<<<<
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+ *     if mutable_raw == NULL:
+ */
+
+static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw_ptr_or_raise(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self) {
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_v_mutable_raw;
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("_mutable_raw_ptr_or_raise", 0);
+
+  /* "pywrapfst.pyx":947
+ *   # fst.SymbolTable is required.
+ *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()             # <<<<<<<<<<<<<<
+ *     if mutable_raw == NULL:
+ *       self._raise_nonexistent()
+ */
+  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_v_mutable_raw = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
+
+  /* "pywrapfst.pyx":948
+ *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+ *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
+ *       self._raise_nonexistent()
+ *     return mutable_raw
+ */
+  __pyx_t_1 = ((__pyx_v_mutable_raw == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "pywrapfst.pyx":949
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+ *     if mutable_raw == NULL:
+ *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
+ *     return mutable_raw
+ * 
+ */
+    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)
+    }
+    ((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)
+
+    /* "pywrapfst.pyx":948
+ *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+ *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
+ *       self._raise_nonexistent()
+ *     return mutable_raw
+ */
+  }
+
+  /* "pywrapfst.pyx":950
+ *     if mutable_raw == NULL:
+ *       self._raise_nonexistent()
+ *     return mutable_raw             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:
+ */
+  __pyx_r = __pyx_v_mutable_raw;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":946
+ *   # 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 *:             # <<<<<<<<<<<<<<
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+ *     if mutable_raw == NULL:
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_AddTraceback("pywrapfst._MutableSymbolTable._mutable_raw_ptr_or_raise", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":952
+ *     return mutable_raw
+ * 
+ *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add_symbol(self, symbol, key=NO_SYMBOL)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static __pyx_t_10basictypes_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) {
-  __pyx_t_10basictypes_int64 __pyx_v_key = __pyx_k__3;
-  std::string __pyx_v_symbol_string;
-  __pyx_t_10basictypes_int64 __pyx_r;
+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;
+  std::string __pyx_v__symbol;
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_v_mutable_raw;
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -11040,9 +11529,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   PyObject *__pyx_t_5 = NULL;
   int __pyx_t_6;
   PyObject *__pyx_t_7 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_8;
+  int64 __pyx_t_8;
   std::string __pyx_t_9;
-  int __pyx_t_10;
+  fst::SymbolTable *__pyx_t_10;
+  int __pyx_t_11;
   __Pyx_RefNannySetupContext("add_symbol", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -11058,10 +11548,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
     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, 900, __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, 952, __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, 900, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 952, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -11079,7 +11569,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
         #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, 900, __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, 952, __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;
@@ -11088,14 +11578,14 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
         #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, 900, __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, 952, __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, 900, __pyx_L1_error)
+          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 952, __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;
@@ -11106,12 +11596,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
           __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, 900, __pyx_L1_error)
+          __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_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 900, __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, 952, __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;
@@ -11130,69 +11620,75 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
     #endif
   }
 
-  /* "pywrapfst.pyx":917
+  /* "pywrapfst.pyx":969
  *       The integer key of the new symbol.
  *     """
- *     cdef string symbol_string = tostring(symbol)             # <<<<<<<<<<<<<<
+ *     cdef string _symbol = tostring(symbol)             # <<<<<<<<<<<<<<
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:
- *       return self._table.AddSymbol(symbol_string, key)
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 917, __pyx_L1_error)
-  __pyx_v_symbol_string = __pyx_t_9;
+  __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":918
+  /* "pywrapfst.pyx":970
  *     """
- *     cdef string symbol_string = tostring(symbol)
+ *     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_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;
+
+  /* "pywrapfst.pyx":971
+ *     cdef string _symbol = tostring(symbol)
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
- *       return self._table.AddSymbol(symbol_string, key)
+ *       return mutable_raw.AddSymbol(_symbol, key)
  *     else:
  */
-  __pyx_t_10 = ((__pyx_v_key != fst::kNoSymbol) != 0);
-  if (__pyx_t_10) {
+  __pyx_t_11 = ((__pyx_v_key != fst::kNoSymbol) != 0);
+  if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":919
- *     cdef string symbol_string = tostring(symbol)
+    /* "pywrapfst.pyx":972
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:
- *       return self._table.AddSymbol(symbol_string, key)             # <<<<<<<<<<<<<<
+ *       return mutable_raw.AddSymbol(_symbol, key)             # <<<<<<<<<<<<<<
  *     else:
- *       return self._table.AddSymbol(symbol_string)
+ *       return mutable_raw.AddSymbol(_symbol)
  */
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 919, __pyx_L1_error)
-    }
-    __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_v_symbol_string, __pyx_v_key);
+    __pyx_r = __pyx_v_mutable_raw->AddSymbol(__pyx_v__symbol, __pyx_v_key);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":918
- *     """
- *     cdef string symbol_string = tostring(symbol)
+    /* "pywrapfst.pyx":971
+ *     cdef string _symbol = tostring(symbol)
+ *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
- *       return self._table.AddSymbol(symbol_string, key)
+ *       return mutable_raw.AddSymbol(_symbol, key)
  *     else:
  */
   }
 
-  /* "pywrapfst.pyx":921
- *       return self._table.AddSymbol(symbol_string, key)
+  /* "pywrapfst.pyx":974
+ *       return mutable_raw.AddSymbol(_symbol, key)
  *     else:
- *       return self._table.AddSymbol(symbol_string)             # <<<<<<<<<<<<<<
+ *       return mutable_raw.AddSymbol(_symbol)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void add_table(self, _SymbolTable syms):
+ *   cpdef void add_table(self, _SymbolTable syms) except *:
  */
   /*else*/ {
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 921, __pyx_L1_error)
-    }
-    __pyx_r = __pyx_v_self->__pyx_base._table->AddSymbol(__pyx_v_symbol_string);
+    __pyx_r = __pyx_v_mutable_raw->AddSymbol(__pyx_v__symbol);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":900
- *   """
+  /* "pywrapfst.pyx":952
+ *     return mutable_raw
  * 
- *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
+ *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add_symbol(self, symbol, key=NO_SYMBOL)
  */
@@ -11205,7 +11701,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_s
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_WriteUnraisable("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -11217,7 +11713,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
 static char __pyx_doc_9pywrapfst_19_MutableSymbolTable_add_symbol[] = "\n    add_symbol(self, symbol, key=NO_SYMBOL)\n\n    Adds a symbol to the table and returns the index.\n\n    This method adds a symbol to the table. The caller can optionally\n    specify a non-negative integer index for the key.\n\n    Args:\n      symbol: A symbol string.\n      key: An index for the symbol; if not specified, the next index will be\n          used.\n\n    Returns:\n      The integer key of the new symbol.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_symbol = 0;
-  __pyx_t_10basictypes_int64 __pyx_v_key;
+  int64 __pyx_v_key;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_symbol (wrapper)", 0);
@@ -11248,7 +11744,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, 900, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 952, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -11261,14 +11757,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 900, __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, 952, __pyx_L3_error)
     } else {
       __pyx_v_key = __pyx_k__3;
     }
   }
   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, 900, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 952, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -11281,18 +11777,18 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_symbol, __pyx_t_10basictypes_int64 __pyx_v_key) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __pyx_t_10basictypes_int64 __pyx_t_1;
+  int64 __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
   __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); 
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 900, __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, 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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -11309,10 +11805,10 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":923
- *       return self._table.AddSymbol(symbol_string)
+/* "pywrapfst.pyx":976
+ *       return mutable_raw.AddSymbol(_symbol)
  * 
- *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   cpdef void add_table(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add_table(self, syms)
  */
@@ -11324,6 +11820,8 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  fst::SymbolTable *__pyx_t_5;
+  fst::SymbolTable const *__pyx_t_6;
   __Pyx_RefNannySetupContext("add_table", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -11334,7 +11832,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, 923, __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, 976, __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);
@@ -11350,7 +11848,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
         }
         __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_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 923, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 976, __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;
@@ -11370,27 +11868,29 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":935
+  /* "pywrapfst.pyx":988
  *       syms: A SymbolTable to be merged with the current table.
  *     """
- *     self._table.AddTable(deref(syms._table))             # <<<<<<<<<<<<<<
+ *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._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'", "_table");
-    __PYX_ERR(0, 935, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
+    __PYX_ERR(0, 988, __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)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 935, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 988, __pyx_L1_error)
   }
-  __pyx_v_self->__pyx_base._table->AddTable((*__pyx_v_syms->_table));
+  __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_5->AddTable((*__pyx_t_6));
 
-  /* "pywrapfst.pyx":923
- *       return self._table.AddSymbol(symbol_string)
+  /* "pywrapfst.pyx":976
+ *       return mutable_raw.AddSymbol(_symbol)
  * 
- *   cpdef void add_table(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   cpdef void add_table(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add_table(self, syms)
  */
@@ -11402,7 +11902,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._MutableSymbolTable.add_table", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
@@ -11414,7 +11914,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *
   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, 923, __pyx_L1_error)
+  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));
 
   /* function exit code */
@@ -11432,7 +11932,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("add_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_syms, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 923, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11449,11 +11950,11 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":937
- *     self._table.AddTable(deref(syms._table))
+/* "pywrapfst.pyx":990
+ *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
- *     self._table.SetName(tostring(new_name))
+ *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
  * 
  */
 
@@ -11464,7 +11965,8 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
+  fst::SymbolTable *__pyx_t_5;
+  std::string __pyx_t_6;
   __Pyx_RefNannySetupContext("set_name", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -11475,7 +11977,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, 937, __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, 990, __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);
@@ -11491,7 +11993,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, 937, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 990, __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;
@@ -11511,25 +12013,26 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":938
+  /* "pywrapfst.pyx":991
  * 
  *   cpdef void set_name(self, new_name) except *:
- *     self._table.SetName(tostring(new_name))             # <<<<<<<<<<<<<<
+ *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 938, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
+    __PYX_ERR(0, 991, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 938, __pyx_L1_error)
-  __pyx_v_self->__pyx_base._table->SetName(__pyx_t_5);
+  __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->SetName(__pyx_t_6);
 
-  /* "pywrapfst.pyx":937
- *     self._table.AddTable(deref(syms._table))
+  /* "pywrapfst.pyx":990
+ *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
- *     self._table.SetName(tostring(new_name))
+ *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
  * 
  */
 
@@ -11564,8 +12067,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   PyObject *__pyx_t_1 = NULL;
   __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, 937, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 937, __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, 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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11582,115 +12085,117 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":948
+/* "pywrapfst.pyx":1001
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_22_MutableFstSymbolTable_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_22_MutableFstSymbolTable_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_26_MutableFstSymbolTableView_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_26_MutableFstSymbolTableView_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(((struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":949
+  /* "pywrapfst.pyx":1002
  * 
  *   def __repr__(self):
- *     return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
- * 
+ *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
  * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 949, __pyx_L1_error)
+  __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);
   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_ERR(0, 1002, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable *)__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(!__pyx_t_3)) __PYX_ERR(0, 949, __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, 949, __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 = NULL;
-  __pyx_t_6 = 0;
+  __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_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 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)) {
+    __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_5);
+      __Pyx_INCREF(__pyx_t_6);
       __Pyx_INCREF(function);
       __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
+      __pyx_t_7 = 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, 949, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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[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, 949, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 949, __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_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_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;
+    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_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 949, __pyx_L1_error)
+    __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_7); __pyx_t_7 = 0;
+    __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":948
+  /* "pywrapfst.pyx":1001
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  */
 
@@ -11698,11 +12203,11 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   __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._MutableFstSymbolTable.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -11710,7 +12215,73 @@ static PyObject *__pyx_pf_9pywrapfst_22_MutableFstSymbolTable___repr__(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":969
+/* "pywrapfst.pyx":1004
+ *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
+ *             self._mfst.get().MutableOutputSymbols())
+ */
+
+static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbolTableView__mutable_raw(struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v_self) {
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
+  __Pyx_RefNannyDeclarations
+  fst::SymbolTable *__pyx_t_1;
+  __Pyx_RefNannySetupContext("_mutable_raw", 0);
+
+  /* "pywrapfst.pyx":1005
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):
+ *     return (self._mfst.get().MutableInputSymbols() if self._input_side else             # <<<<<<<<<<<<<<
+ *             self._mfst.get().MutableOutputSymbols())
+ * 
+ */
+  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)
+  }
+  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_t_1 = __pyx_v_self->_mfst.get()->MutableInputSymbols();
+  } else {
+
+    /* "pywrapfst.pyx":1006
+ *   cdef SymbolTable_ptr _mutable_raw(self):
+ *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
+ *             self._mfst.get().MutableOutputSymbols())             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    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_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))
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
+ *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
+ *             self._mfst.get().MutableOutputSymbols())
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_WriteUnraisable("pywrapfst._MutableFstSymbolTableView._mutable_raw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1026
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11736,14 +12307,15 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":970
+  /* "pywrapfst.pyx":1027
  * 
  *   def __repr__(self):
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
@@ -11751,70 +12323,71 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
  *   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, 970, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 970, __pyx_L1_error)
+    __PYX_ERR(0, 1027, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((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(!__pyx_t_3)) __PYX_ERR(0, 970, __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, 970, __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 = NULL;
-  __pyx_t_6 = 0;
+  __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_GOTREF(__pyx_t_5);
+  __pyx_t_6 = NULL;
+  __pyx_t_7 = 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)) {
+    __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_5);
+      __Pyx_INCREF(__pyx_t_6);
       __Pyx_INCREF(function);
       __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
+      __pyx_t_7 = 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, 970, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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[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, 970, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    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_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_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 970, __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_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_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;
+    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_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 970, __pyx_L1_error)
+    __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_7); __pyx_t_7 = 0;
+    __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":969
+  /* "pywrapfst.pyx":1026
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -11826,10 +12399,10 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   __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_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:;
@@ -11838,12 +12411,12 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":972
+/* "pywrapfst.pyx":1029
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
- *     self._table = new fst.SymbolTable(tostring(name))
- *     self._smart_table.reset(self._table)
+ *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
+ * 
  */
 
 /* Python wrapper */
@@ -11875,7 +12448,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, 972, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1029, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -11889,7 +12462,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, 972, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1029, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -11908,43 +12481,26 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   std::string __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":973
+  /* "pywrapfst.pyx":1030
  * 
  *   def __init__(self, name="<unspecified>"):
- *     self._table = new fst.SymbolTable(tostring(name))             # <<<<<<<<<<<<<<
- *     self._smart_table.reset(self._table)
+ *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))             # <<<<<<<<<<<<<<
  * 
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 973, __pyx_L1_error)
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 973, __pyx_L1_error)
-  }
-  __pyx_v_self->__pyx_base.__pyx_base._table = new fst::SymbolTable(__pyx_t_1);
-
-  /* "pywrapfst.pyx":974
- *   def __init__(self, name="<unspecified>"):
- *     self._table = new fst.SymbolTable(tostring(name))
- *     self._smart_table.reset(self._table)             # <<<<<<<<<<<<<<
- * 
- *   @classmethod
+ *   cdef SymbolTable_ptr _mutable_raw(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 974, __pyx_L1_error)
+    __PYX_ERR(0, 1030, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 974, __pyx_L1_error)
-  }
-  __pyx_v_self->_smart_table.reset(__pyx_v_self->__pyx_base.__pyx_base._table);
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1030, __pyx_L1_error)
+  __pyx_v_self->_smart_table.reset(new fst::SymbolTable(__pyx_t_1));
 
-  /* "pywrapfst.pyx":972
+  /* "pywrapfst.pyx":1029
  *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
- *     self._table = new fst.SymbolTable(tostring(name))
- *     self._smart_table.reset(self._table)
+ *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
+ * 
  */
 
   /* function exit code */
@@ -11958,7 +12514,51 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":977
+/* "pywrapfst.pyx":1032
+ *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
+ *     return self._smart_table.get()
+ * 
+ */
+
+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
+  __Pyx_RefNannySetupContext("_mutable_raw", 0);
+
+  /* "pywrapfst.pyx":1033
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):
+ *     return self._smart_table.get()             # <<<<<<<<<<<<<<
+ * 
+ *   @classmethod
+ */
+  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_r = __pyx_v_self->_smart_table.get();
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1032
+ *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
+ * 
+ *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
+ *     return self._smart_table.get()
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_WriteUnraisable("pywrapfst.SymbolTable._mutable_raw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1036
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -11993,36 +12593,36 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":992
+  /* "pywrapfst.pyx":1051
  *     """
  *     cdef unique_ptr[fst.SymbolTable] syms
  *     syms.reset(fst.SymbolTable.Read(tostring(source)))             # <<<<<<<<<<<<<<
  *     if syms.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 992, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":993
+  /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":994
+    /* "pywrapfst.pyx":1053
  *     syms.reset(fst.SymbolTable.Read(tostring(source)))
  *     if syms.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     return _init_SymbolTable(syms.release())
+ *     return _init_SymbolTable(move(syms))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 994, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1053, __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, 994, __pyx_L1_error)
+    __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))) {
@@ -12036,7 +12636,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
     }
     __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, 994, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1053, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12052,37 +12652,37 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
     __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, 994, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1053, __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, 994, __pyx_L1_error)
+    __PYX_ERR(0, 1053, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":993
+    /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   }
 
-  /* "pywrapfst.pyx":995
+  /* "pywrapfst.pyx":1054
  *     if syms.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 995, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":977
+  /* "pywrapfst.pyx":1036
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -12105,7 +12705,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":998
+/* "pywrapfst.pyx":1057
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12149,7 +12749,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, 998, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 1057, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12162,14 +12762,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, 998, __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, 1057, __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, 998, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1057, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12196,7 +12796,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read_text", 0);
 
-  /* "pywrapfst.pyx":1015
+  /* "pywrapfst.pyx":1074
  *     """
  *     cdef unique_ptr[fst.SymbolTableTextOptions] opts
  *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
@@ -12205,36 +12805,36 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
  */
   __pyx_v_opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
 
-  /* "pywrapfst.pyx":1017
+  /* "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))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __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)));
 
-  /* "pywrapfst.pyx":1018
+  /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1019
+    /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1019, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1078, __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, 1019, __pyx_L1_error)
+    __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))) {
@@ -12248,7 +12848,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
     }
     __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, 1019, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1078, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12264,37 +12864,37 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
     __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, 1019, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1078, __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, 1019, __pyx_L1_error)
+    __PYX_ERR(0, 1078, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1018
+    /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   }
 
-  /* "pywrapfst.pyx":1020
+  /* "pywrapfst.pyx":1079
  *     if syms.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1020, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":998
+  /* "pywrapfst.pyx":1057
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12317,7 +12917,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1023
+/* "pywrapfst.pyx":1082
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -12357,11 +12957,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, 1023, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1082, __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, 1023, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1082, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -12370,11 +12970,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, 1023, __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, 1082, __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, 1023, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1082, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12400,36 +13000,36 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read_fst", 0);
 
-  /* "pywrapfst.pyx":1044
+  /* "pywrapfst.pyx":1103
  *     """
  *     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))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1044, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":1045
+  /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1046
+    /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1046, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1105, __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, 1046, __pyx_L1_error)
+    __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))) {
@@ -12443,7 +13043,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
     }
     __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, 1046, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1105, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -12459,37 +13059,37 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
     __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, 1046, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1105, __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, 1046, __pyx_L1_error)
+    __PYX_ERR(0, 1105, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1045
+    /* "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(syms.release())
+ *     return _init_SymbolTable(move(syms))
  */
   }
 
-  /* "pywrapfst.pyx":1047
+  /* "pywrapfst.pyx":1106
  *     if syms.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1047, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1023
+  /* "pywrapfst.pyx":1082
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -12512,62 +13112,62 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1050
+/* "pywrapfst.pyx":1109
  * 
  * 
- * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
- *   cdef _EncodeMapperSymbolTable result = (
+ * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
+ *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
+ *   cdef _EncodeMapperSymbolTableView result = (
  */
 
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(fst::SymbolTable *__pyx_v_table, std::shared_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper) {
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_v_result = 0;
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
+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_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTable", 0);
+  __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1053
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
- *   cdef _EncodeMapperSymbolTable result = (
- *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))             # <<<<<<<<<<<<<<
- *   result._table = table
- *   result._mapper = mapper
+  /* "pywrapfst.pyx":1112
+ *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
+ *   cdef _EncodeMapperSymbolTableView result = (
+ *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))             # <<<<<<<<<<<<<<
+ *   result._mapper = move(mapper)
+ *   result._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1053, __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, 1112, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
+  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1054
- *   cdef _EncodeMapperSymbolTable result = (
- *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
- *   result._table = table             # <<<<<<<<<<<<<<
- *   result._mapper = mapper
+  /* "pywrapfst.pyx":1113
+ *   cdef _EncodeMapperSymbolTableView result = (
+ *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
+ *   result._mapper = move(mapper)             # <<<<<<<<<<<<<<
+ *   result._input_side = input_side
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1054, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
+    __PYX_ERR(0, 1113, __pyx_L1_error)
   }
-  __pyx_v_result->__pyx_base._table = __pyx_v_table;
+  __pyx_v_result->_mapper = fst::move<std::shared_ptr<fst::script::EncodeMapperClass> >(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1055
- *       _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
- *   result._table = table
- *   result._mapper = mapper             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1114
+ *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
+ *   result._mapper = move(mapper)
+ *   result._input_side = input_side             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1055, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
+    __PYX_ERR(0, 1114, __pyx_L1_error)
   }
-  __pyx_v_result->_mapper = __pyx_v_mapper;
+  __pyx_v_result->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1056
- *   result._table = table
- *   result._mapper = mapper
+  /* "pywrapfst.pyx":1115
+ *   result._mapper = move(mapper)
+ *   result._input_side = input_side
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -12577,18 +13177,18 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1050
+  /* "pywrapfst.pyx":1109
  * 
  * 
- * cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(             # <<<<<<<<<<<<<<
- *     fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
- *   cdef _EncodeMapperSymbolTable result = (
+ * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
+ *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
+ *   cdef _EncodeMapperSymbolTableView result = (
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._init_EncodeMapperSymbolTable", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._init_EncodeMapperSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XDECREF((PyObject *)__pyx_v_result);
@@ -12597,62 +13197,62 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1059
+/* "pywrapfst.pyx":1118
  * 
  * 
- * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
- *                                           shared_ptr[fst.FstClass] ifst):
- *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
+ * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
+ *                                                   bool input_side):
+ *   cdef _FstSymbolTableView result = (
  */
 
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_FstSymbolTable(fst::SymbolTable *__pyx_v_table, std::shared_ptr<fst::script::FstClass>  __pyx_v_ifst) {
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_v_result = 0;
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_r = NULL;
+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_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("_init_FstSymbolTable", 0);
+  __Pyx_RefNannySetupContext("_init_FstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1061
- * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
- *                                           shared_ptr[fst.FstClass] ifst):
- *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)             # <<<<<<<<<<<<<<
- *   result._table = table
- *   result._fst = ifst
+  /* "pywrapfst.pyx":1121
+ *                                                   bool input_side):
+ *   cdef _FstSymbolTableView result = (
+ *       _FstSymbolTableView.__new__(_FstSymbolTableView))             # <<<<<<<<<<<<<<
+ *   result._fst = move(ifst)
+ *   result._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1061, __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, 1121, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
+  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1062
- *                                           shared_ptr[fst.FstClass] ifst):
- *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
- *   result._table = table             # <<<<<<<<<<<<<<
- *   result._fst = ifst
+  /* "pywrapfst.pyx":1122
+ *   cdef _FstSymbolTableView result = (
+ *       _FstSymbolTableView.__new__(_FstSymbolTableView))
+ *   result._fst = move(ifst)             # <<<<<<<<<<<<<<
+ *   result._input_side = input_side
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1062, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1122, __pyx_L1_error)
   }
-  __pyx_v_result->__pyx_base._table = __pyx_v_table;
+  __pyx_v_result->_fst = fst::move<std::shared_ptr<fst::script::FstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1063
- *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
- *   result._table = table
- *   result._fst = ifst             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1123
+ *       _FstSymbolTableView.__new__(_FstSymbolTableView))
+ *   result._fst = move(ifst)
+ *   result._input_side = input_side             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1063, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
+    __PYX_ERR(0, 1123, __pyx_L1_error)
   }
-  __pyx_v_result->_fst = __pyx_v_ifst;
+  __pyx_v_result->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1064
- *   result._table = table
- *   result._fst = ifst
+  /* "pywrapfst.pyx":1124
+ *   result._fst = move(ifst)
+ *   result._input_side = input_side
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -12662,18 +13262,18 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1059
+  /* "pywrapfst.pyx":1118
  * 
  * 
- * cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
- *                                           shared_ptr[fst.FstClass] ifst):
- *   cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
+ * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
+ *                                                   bool input_side):
+ *   cdef _FstSymbolTableView result = (
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._init_FstSymbolTable", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._init_FstSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XDECREF((PyObject *)__pyx_v_result);
@@ -12682,62 +13282,62 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst__init_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1067
+/* "pywrapfst.pyx":1127
  * 
  * 
- * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
- *     shared_ptr[fst.MutableFstClass] ifst):
- *   cdef _MutableFstSymbolTable result = (
+ * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
+ *                                     shared_ptr[fst.MutableFstClass] ifst,
+ *                                     bool input_side):
  */
 
-static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__init_MutableFstSymbolTable(fst::SymbolTable *__pyx_v_table, std::shared_ptr<fst::script::MutableFstClass>  __pyx_v_ifst) {
-  struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_v_result = 0;
-  struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_r = NULL;
+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_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("_init_MutableFstSymbolTable", 0);
+  __Pyx_RefNannySetupContext("_init_MutableFstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1070
- *     shared_ptr[fst.MutableFstClass] ifst):
- *   cdef _MutableFstSymbolTable result = (
- *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))             # <<<<<<<<<<<<<<
- *   result._table = table
- *   result._mfst = ifst
+  /* "pywrapfst.pyx":1131
+ *                                     bool input_side):
+ *   cdef _MutableFstSymbolTableView result = (
+ *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))             # <<<<<<<<<<<<<<
+ *   result._mfst = move(ifst)
+ *   result._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1070, __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, 1131, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)__pyx_t_1);
+  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1071
- *   cdef _MutableFstSymbolTable result = (
- *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
- *   result._table = table             # <<<<<<<<<<<<<<
- *   result._mfst = ifst
+  /* "pywrapfst.pyx":1132
+ *   cdef _MutableFstSymbolTableView result = (
+ *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
+ *   result._mfst = move(ifst)             # <<<<<<<<<<<<<<
+ *   result._input_side = input_side
  *   return result
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1071, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
+    __PYX_ERR(0, 1132, __pyx_L1_error)
   }
-  __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
+  __pyx_v_result->_mfst = fst::move<std::shared_ptr<fst::script::MutableFstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1072
- *       _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
- *   result._table = table
- *   result._mfst = ifst             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1133
+ *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
+ *   result._mfst = move(ifst)
+ *   result._input_side = input_side             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1072, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
+    __PYX_ERR(0, 1133, __pyx_L1_error)
   }
-  __pyx_v_result->_mfst = __pyx_v_ifst;
+  __pyx_v_result->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1073
- *   result._table = table
- *   result._mfst = ifst
+  /* "pywrapfst.pyx":1134
+ *   result._mfst = move(ifst)
+ *   result._input_side = input_side
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -12747,18 +13347,18 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1067
+  /* "pywrapfst.pyx":1127
  * 
  * 
- * cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,             # <<<<<<<<<<<<<<
- *     shared_ptr[fst.MutableFstClass] ifst):
- *   cdef _MutableFstSymbolTable result = (
+ * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
+ *                                     shared_ptr[fst.MutableFstClass] ifst,
+ *                                     bool input_side):
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._init_MutableFstSymbolTable", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._init_MutableFstSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XDECREF((PyObject *)__pyx_v_result);
@@ -12767,49 +13367,49 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *__pyx_f_9pywrapfst__i
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1076
+/* "pywrapfst.pyx":1137
  * 
  * 
- * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):             # <<<<<<<<<<<<<<
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._table = table
+ *   result._smart_table = move(table)
  */
 
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(fst::SymbolTable *__pyx_v_table) {
+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;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_SymbolTable", 0);
 
-  /* "pywrapfst.pyx":1077
+  /* "pywrapfst.pyx":1138
  * 
- * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
- *   result._table = table
+ *   result._smart_table = move(table)
  *   return result
  */
-  __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, 1077, __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, 1138, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1078
- * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
+  /* "pywrapfst.pyx":1139
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._table = table             # <<<<<<<<<<<<<<
+ *   result._smart_table = move(table)             # <<<<<<<<<<<<<<
  *   return result
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1078, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
+    __PYX_ERR(0, 1139, __pyx_L1_error)
   }
-  __pyx_v_result->__pyx_base.__pyx_base._table = __pyx_v_table;
+  __pyx_v_result->_smart_table = fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_table);
 
-  /* "pywrapfst.pyx":1079
+  /* "pywrapfst.pyx":1140
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._table = table
+ *   result._smart_table = move(table)
  *   return result             # <<<<<<<<<<<<<<
  * 
  * 
@@ -12819,12 +13419,12 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1076
+  /* "pywrapfst.pyx":1137
  * 
  * 
- * cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):             # <<<<<<<<<<<<<<
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):             # <<<<<<<<<<<<<<
  *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._table = table
+ *   result._smart_table = move(table)
  */
 
   /* function exit code */
@@ -12839,7 +13439,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1082
+/* "pywrapfst.pyx":1143
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
@@ -12860,17 +13460,17 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
 
-  /* "pywrapfst.pyx":1084
+  /* "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, 1084, __pyx_L1_error)
+  __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":1086
+  /* "pywrapfst.pyx":1147
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.SymbolTable] syms
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -12879,24 +13479,24 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
  */
   __pyx_v_syms.reset(fst::SymbolTable::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1087
+  /* "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(syms.release())
+ *   return _init_SymbolTable(move(syms))
  */
   __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1088
+    /* "pywrapfst.pyx":1149
  *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
  *   if syms.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
- *   return _init_SymbolTable(syms.release())
+ *   return _init_SymbolTable(move(syms))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error)
+    __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))) {
@@ -12910,37 +13510,37 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
     }
     __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, 1088, __pyx_L1_error)
+    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_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1088, __pyx_L1_error)
+    __PYX_ERR(0, 1149, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1087
+    /* "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(syms.release())
+ *   return _init_SymbolTable(move(syms))
  */
   }
 
-  /* "pywrapfst.pyx":1089
+  /* "pywrapfst.pyx":1150
  *   if syms.get() == NULL:
  *     raise FstIOError("Read failed")
- *   return _init_SymbolTable(syms.release())             # <<<<<<<<<<<<<<
+ *   return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(__pyx_v_syms.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1089, __pyx_L1_error)
+  __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1082
+  /* "pywrapfst.pyx":1143
  * 
  * 
  * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
@@ -12980,7 +13580,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   PyObject *__pyx_t_1 = NULL;
   __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, 1082, __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, 1143, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -12997,7 +13597,7 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1095
+/* "pywrapfst.pyx":1156
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13009,28 +13609,46 @@ static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self
 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) {
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  fst::SymbolTable const *__pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1107
+  /* "pywrapfst.pyx":1168
  *     A new compacted SymbolTable.
  *   """
- *   return _init_SymbolTable(fst.CompactSymbolTable(deref(syms._table)))             # <<<<<<<<<<<<<<
- * 
+ *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
+ *                                           deref(syms._raw_ptr_or_raise()))))
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+  /* "pywrapfst.pyx":1169
+ *   """
+ *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(
+ *                                           deref(syms._raw_ptr_or_raise()))))             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1107, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 1169, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::CompactSymbolTable((*__pyx_v_syms->_table)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1107, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  __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)
+
+  /* "pywrapfst.pyx":1168
+ *     A new compacted SymbolTable.
+ *   """
+ *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
+ *                                           deref(syms._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_GOTREF(__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1095
+  /* "pywrapfst.pyx":1156
  * 
  * 
  * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
@@ -13040,7 +13658,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst.compact_symbol_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -13056,7 +13674,7 @@ static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self
   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, 1095, __pyx_L1_error)
+  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));
 
   /* function exit code */
@@ -13074,7 +13692,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   PyObject *__pyx_t_1 = NULL;
   __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, 1095, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13091,7 +13709,7 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1110
+/* "pywrapfst.pyx":1172
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13103,48 +13721,60 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
 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) {
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  fst::SymbolTable const *__pyx_t_1;
+  fst::SymbolTable const *__pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1132
+  /* "pywrapfst.pyx":1194
  *     A new merged SymbolTable.
  *   """
- *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),             # <<<<<<<<<<<<<<
- *                                                 deref(rhs._table), NULL))
- * 
+ *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
+ *                                           deref(lhs._raw_ptr_or_raise()),
+ *                                           deref(rhs._raw_ptr_or_raise()),
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+  /* "pywrapfst.pyx":1195
+ *   """
+ *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
+ *                                           deref(lhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
+ *                                           deref(rhs._raw_ptr_or_raise()),
+ *                                           NULL)))
+ */
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1132, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 1195, __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)
 
-  /* "pywrapfst.pyx":1133
- *   """
- *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),
- *                                                 deref(rhs._table), NULL))             # <<<<<<<<<<<<<<
- * 
+  /* "pywrapfst.pyx":1196
+ *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
+ *                                           deref(lhs._raw_ptr_or_raise()),
+ *                                           deref(rhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
+ *                                           NULL)))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1133, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 1196, __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)
 
-  /* "pywrapfst.pyx":1132
+  /* "pywrapfst.pyx":1194
  *     A new merged SymbolTable.
  *   """
- *   return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),             # <<<<<<<<<<<<<<
- *                                                 deref(rhs._table), NULL))
- * 
+ *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
+ *                                           deref(lhs._raw_ptr_or_raise()),
+ *                                           deref(rhs._raw_ptr_or_raise()),
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::MergeSymbolTable((*__pyx_v_lhs->_table), (*__pyx_v_rhs->_table), NULL))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1132, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  __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_GOTREF(__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_3);
+  __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1110
+  /* "pywrapfst.pyx":1172
  * 
  * 
  * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
@@ -13154,7 +13784,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_AddTraceback("pywrapfst.merge_symbol_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -13195,11 +13825,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, 1110, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1172, __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, 1110, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1172, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -13212,14 +13842,14 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
   }
   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, 1110, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1172, __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, 1110, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1110, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_12merge_symbol_table(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -13237,7 +13867,7 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   PyObject *__pyx_t_1 = NULL;
   __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, 1110, __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, 1172, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13254,28 +13884,28 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1147
+/* "pywrapfst.pyx":1210
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
+ *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_1__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_1__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_1__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -13284,17 +13914,17 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1148
+  /* "pywrapfst.pyx":1211
  * 
  *   def __repr__(self):
- *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, _SymbolTable syms):
  */
   __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, 1148, __pyx_L1_error)
+  __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, 1148, __pyx_L1_error)
+  __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))) {
@@ -13309,18 +13939,18 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   __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, 1148, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1211, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1147
+  /* "pywrapfst.pyx":1210
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
+ *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  */
 
@@ -13330,7 +13960,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -13338,17 +13968,17 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator___repr__(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1150
- *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":1213
+ *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
- *     self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))
- * 
+ *     self._table = syms
+ *     self._siter.reset(new fst.SymbolTableIterator(
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+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;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -13372,7 +14002,7 @@ static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(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, "__init__") < 0)) __PYX_ERR(0, 1150, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1213, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -13383,14 +14013,14 @@ static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1150, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1213, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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, 1150, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self), __pyx_v_syms);
+  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);
 
   /* function exit code */
   goto __pyx_L0;
@@ -13401,48 +14031,87 @@ static int __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__(PyObject *__pyx_v
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_19SymbolTableIterator_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__SymbolTable *__pyx_v_syms) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
+  fst::SymbolTable const *__pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1151
+  /* "pywrapfst.pyx":1214
  * 
  *   def __init__(self, _SymbolTable syms):
- *     self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))             # <<<<<<<<<<<<<<
+ *     self._table = syms             # <<<<<<<<<<<<<<
+ *     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_INCREF(((PyObject *)__pyx_v_syms));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_syms));
+  __Pyx_GOTREF(__pyx_v_self->_table);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->_table));
+  __pyx_v_self->_table = __pyx_v_syms;
+
+  /* "pywrapfst.pyx":1215
+ *   def __init__(self, _SymbolTable syms):
+ *     self._table = syms
+ *     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'", "_siter");
-    __PYX_ERR(0, 1151, __pyx_L1_error)
+    __PYX_ERR(0, 1215, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+
+  /* "pywrapfst.pyx":1216
+ *     self._table = syms
+ *     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, 1151, __pyx_L1_error)
+    __PYX_ERR(0, 1216, __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_v_self->_siter.reset(new fst::SymbolTableIterator((*__pyx_v_syms->_table)));
+  __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)
 
-  /* "pywrapfst.pyx":1150
- *     return "<SymbolTableIterator at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":1215
+ *   def __init__(self, _SymbolTable syms):
+ *     self._table = syms
+ *     self._siter.reset(new fst.SymbolTableIterator(             # <<<<<<<<<<<<<<
+ *                           self._table._raw_ptr_or_raise().begin()))
  * 
- *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
- *     self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))
+ */
+  __pyx_v_self->_siter.reset(new fst::SymbolTable::iterator(__pyx_t_1->begin()));
+
+  /* "pywrapfst.pyx":1213
+ *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
  * 
+ *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *     self._table = syms
+ *     self._siter.reset(new fst.SymbolTableIterator(
  */
 
   /* function exit code */
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1154
+/* "pywrapfst.pyx":1219
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13451,24 +14120,24 @@ static int __pyx_pf_9pywrapfst_19SymbolTableIterator_2__init__(struct __pyx_obj_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_5__iter__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_5__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_5__iter__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":1155
+  /* "pywrapfst.pyx":1220
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -13480,7 +14149,7 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1154
+  /* "pywrapfst.pyx":1219
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -13495,821 +14164,158 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_4__iter__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1158
+/* "pywrapfst.pyx":1223
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
- *     if self.done():
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_6__next__(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  __pyx_t_10basictypes_int64 __pyx_v_value;
+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;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
+  fst::SymbolTable const *__pyx_t_1;
+  int __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":1159
+  /* "pywrapfst.pyx":1224
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
- *     if self.done():             # <<<<<<<<<<<<<<
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
  *       raise StopIteration
- *     cdef int64 value = self.value()
+ *     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'", "done");
-    __PYX_ERR(0, 1159, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
+    __PYX_ERR(0, 1224, __pyx_L1_error)
   }
-  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
-  if (unlikely(__pyx_t_1)) {
+  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_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)
+  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_t_2 = ((__pyx_t_1->end() == (*__pyx_v_self->_siter)) != 0);
+  if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1160
+    /* "pywrapfst.pyx":1225
  *   def __next__(self):
- *     if self.done():
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration             # <<<<<<<<<<<<<<
- *     cdef int64 value = self.value()
- *     cdef string symbol = self.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, 1160, __pyx_L1_error)
+    __PYX_ERR(0, 1225, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1159
+    /* "pywrapfst.pyx":1224
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
- *     if self.done():             # <<<<<<<<<<<<<<
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
  *       raise StopIteration
- *     cdef int64 value = self.value()
+ *     cdef int64 label = self._siter.get().Pair().Label()
  */
   }
 
-  /* "pywrapfst.pyx":1161
- *     if self.done():
+  /* "pywrapfst.pyx":1226
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration
- *     cdef int64 value = self.value()             # <<<<<<<<<<<<<<
- *     cdef string symbol = self.symbol()
- *     self.next()
+ *     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'", "value");
-    __PYX_ERR(0, 1161, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
+    __PYX_ERR(0, 1226, __pyx_L1_error)
   }
-  __pyx_v_value = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
+  __pyx_v_label = __pyx_v_self->_siter.get()->operator*().Label();
 
-  /* "pywrapfst.pyx":1162
+  /* "pywrapfst.pyx":1227
  *       raise StopIteration
- *     cdef int64 value = self.value()
- *     cdef string symbol = self.symbol()             # <<<<<<<<<<<<<<
- *     self.next()
- *     return (value, symbol)
+ *     cdef int64 label = self._siter.get().Pair().Label()
+ *     cdef string symbol = self._siter.get().Pair().Symbol()             # <<<<<<<<<<<<<<
+ *     inc(deref(self._siter))
+ *     return (label, symbol)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "symbol");
-    __PYX_ERR(0, 1162, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
+    __PYX_ERR(0, 1227, __pyx_L1_error)
   }
-  __pyx_v_symbol = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->symbol(__pyx_v_self, 0);
+  __pyx_v_symbol = __pyx_v_self->_siter.get()->operator*().Symbol();
 
-  /* "pywrapfst.pyx":1163
- *     cdef int64 value = self.value()
- *     cdef string symbol = self.symbol()
- *     self.next()             # <<<<<<<<<<<<<<
- *     return (value, symbol)
+  /* "pywrapfst.pyx":1228
+ *     cdef int64 label = self._siter.get().Pair().Label()
+ *     cdef string symbol = self._siter.get().Pair().Symbol()
+ *     inc(deref(self._siter))             # <<<<<<<<<<<<<<
+ *     return (label, symbol)
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 1163, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
+    __PYX_ERR(0, 1228, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
+  (void)((++(*__pyx_v_self->_siter)));
 
-  /* "pywrapfst.pyx":1164
- *     cdef string symbol = self.symbol()
- *     self.next()
- *     return (value, symbol)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1229
+ *     cdef string symbol = self._siter.get().Pair().Symbol()
+ *     inc(deref(self._siter))
+ *     return (label, symbol)             # <<<<<<<<<<<<<<
+ * 
  * 
- *   cpdef bool done(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1164, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1164, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_label); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1229, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1164, __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, 1229, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1229, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
-  __pyx_t_2 = 0;
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
   __pyx_t_3 = 0;
-  __pyx_r = __pyx_t_4;
   __pyx_t_4 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1158
+  /* "pywrapfst.pyx":1223
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
- *     if self.done():
+ *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1166
- *     return (value, symbol)
- * 
- *   cpdef bool done(self):             # <<<<<<<<<<<<<<
- *     """
- *     done(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_19SymbolTableIterator_done(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__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;
-  bool __pyx_t_5;
-  __Pyx_RefNannySetupContext("done", 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_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1166, __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_19SymbolTableIterator_9done)) {
-        __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, 1166, __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, 1166, __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":1175
- *       True if the iterator is exhausted, False otherwise.
- *     """
- *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
- * 
- *   cpdef void next(self):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1175, __pyx_L1_error)
-  }
-  __pyx_r = __pyx_v_self->_siter.get()->Done();
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":1166
- *     return (value, symbol)
- * 
- *   cpdef bool done(self):             # <<<<<<<<<<<<<<
- *     """
- *     done(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.SymbolTableIterator.done", __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_19SymbolTableIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_8done[] = "\n    done(self)\n\n    Indicates whether the iterator is exhausted or not.\n\n    Returns:\n      True if the iterator is exhausted, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_9done(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("done (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_8done(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_8done(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("done", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_19SymbolTableIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1166, __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.SymbolTableIterator.done", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1177
- *     return self._siter.get().Done()
- * 
- *   cpdef void next(self):             # <<<<<<<<<<<<<<
- *     """
- *     next(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_19SymbolTableIterator_next(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("next", 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_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __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_19SymbolTableIterator_11next)) {
-        __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, 1177, __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;
-        __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":1183
- *     Advances the iterator.
- *     """
- *     self._siter.get().Next()             # <<<<<<<<<<<<<<
- * 
- *   cpdef void reset(self):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1183, __pyx_L1_error)
-  }
-  __pyx_v_self->_siter.get()->Next();
-
-  /* "pywrapfst.pyx":1177
- *     return self._siter.get().Done()
- * 
- *   cpdef void next(self):             # <<<<<<<<<<<<<<
- *     """
- *     next(self)
- */
-
-  /* function exit code */
-  goto __pyx_L0;
-  __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.SymbolTableIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_10next[] = "\n    next(self)\n\n    Advances the iterator.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_11next(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("next (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_10next(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_10next(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("next", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __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.SymbolTableIterator.next", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1185
- *     self._siter.get().Next()
- * 
- *   cpdef void reset(self):             # <<<<<<<<<<<<<<
- *     """
- *     reset(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static void __pyx_f_9pywrapfst_19SymbolTableIterator_reset(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("reset", 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_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1185, __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_19SymbolTableIterator_13reset)) {
-        __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, 1185, __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;
-        __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":1191
- *     Resets the iterator to the initial position.
- *     """
- *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
- * 
- *   cpdef string symbol(self):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1191, __pyx_L1_error)
-  }
-  __pyx_v_self->_siter.get()->Reset();
-
-  /* "pywrapfst.pyx":1185
- *     self._siter.get().Next()
- * 
- *   cpdef void reset(self):             # <<<<<<<<<<<<<<
- *     """
- *     reset(self)
- */
-
-  /* function exit code */
-  goto __pyx_L0;
-  __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.SymbolTableIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_12reset[] = "\n    reset(self)\n\n    Resets the iterator to the initial position.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("reset (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_12reset(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("reset", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_19SymbolTableIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1185, __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.SymbolTableIterator.reset", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1193
- *     self._siter.get().Reset()
- * 
- *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
- *     """
- *     symbol(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_19SymbolTableIterator_symbol(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__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("symbol", 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_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __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_19SymbolTableIterator_15symbol)) {
-        __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, 1193, __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, 1193, __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":1204
- *       A symbol string.
- *     """
- *     return self._siter.get().Symbol()             # <<<<<<<<<<<<<<
- * 
- *   cpdef int64 value(self):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1204, __pyx_L1_error)
-  }
-  __pyx_r = __pyx_v_self->_siter.get()->Symbol();
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":1193
- *     self._siter.get().Reset()
- * 
- *   cpdef string symbol(self):             # <<<<<<<<<<<<<<
- *     """
- *     symbol(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.SymbolTableIterator.symbol", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __Pyx_pretend_to_initialize(&__pyx_r);
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_14symbol[] = "\n    symbol(self)\n\n    Returns the current symbol string.\n\n    This method returns the current symbol string at this point in the table.\n\n    Returns:\n      A symbol string.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("symbol (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_14symbol(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("symbol", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_19SymbolTableIterator_symbol(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __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.SymbolTableIterator.symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1206
- *     return self._siter.get().Symbol()
- * 
- *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
- *     """
- *     value(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_17value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_19SymbolTableIterator_value(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
-  __Pyx_RefNannySetupContext("value", 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_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1206, __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_19SymbolTableIterator_17value)) {
-        __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, 1206, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1206, __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":1215
- *       An integer index.
- *     """
- *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  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_r = __pyx_v_self->_siter.get()->Value();
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":1206
- *     return self._siter.get().Symbol()
- * 
- *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
- *     """
- *     value(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.SymbolTableIterator.value", __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_19SymbolTableIterator_17value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_19SymbolTableIterator_16value[] = "\n    value(self)\n\n    Returns the current integer index of the symbol.\n\n    Returns:\n      An integer index.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_17value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("value (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_19SymbolTableIterator_16value(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_16value(struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("value", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_19SymbolTableIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1206, __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.SymbolTableIterator.value", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -14319,24 +14325,24 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_16value(struct __pyx_
 
 /* "(tree fragment)":1
  * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_9__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_9__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_19SymbolTableIterator_18__reduce_cython__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_8__reduce_cython__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_8__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -14344,9 +14350,9 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(C
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     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_GOTREF(__pyx_t_1);
@@ -14356,14 +14362,14 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(C
 
   /* "(tree fragment)":1
  * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
@@ -14372,34 +14378,34 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_18__reduce_cython__(C
 
 /* "(tree fragment)":3
  * def __reduce_cython__(self):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19SymbolTableIterator_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_11__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_11__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_19SymbolTableIterator_20__setstate_cython__(((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
+ *     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_GOTREF(__pyx_t_1);
@@ -14409,22 +14415,22 @@ static PyObject *__pyx_pf_9pywrapfst_19SymbolTableIterator_20__setstate_cython__
 
   /* "(tree fragment)":3
  * def __reduce_cython__(self):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.SymbolTableIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1244
+/* "pywrapfst.pyx":1258
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14454,7 +14460,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1245
+  /* "pywrapfst.pyx":1259
  * 
  *   def __repr__(self):
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -14462,9 +14468,9 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
  *   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, 1245, __pyx_L1_error)
+  __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, 1245, __pyx_L1_error)
+  __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))) {
@@ -14479,14 +14485,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   __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, 1245, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1259, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1244
+  /* "pywrapfst.pyx":1258
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -14508,7 +14514,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1247
+/* "pywrapfst.pyx":1261
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14563,7 +14569,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, 1247, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1261, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -14579,10 +14585,10 @@ 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, 1249, __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, 1263, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1249
+      /* "pywrapfst.pyx":1263
  *   def __init__(self,
  *                arc_type=b"standard",
  *                bool encode_labels=False,             # <<<<<<<<<<<<<<
@@ -14592,10 +14598,10 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
       __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, 1250, __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, 1264, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1250
+      /* "pywrapfst.pyx":1264
  *                arc_type=b"standard",
  *                bool encode_labels=False,
  *                bool encode_weights=False):             # <<<<<<<<<<<<<<
@@ -14607,7 +14613,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1247, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1261, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14615,7 +14621,7 @@ 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":1247
+  /* "pywrapfst.pyx":1261
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14629,7 +14635,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) {
-  __pyx_t_10basictypes_uint8 __pyx_v_flags;
+  uint8 __pyx_v_flags;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -14641,61 +14647,61 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1251
+  /* "pywrapfst.pyx":1265
  *                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))
+ *                                                  fst.ENCODE))
  */
   __pyx_v_flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1252
+  /* "pywrapfst.pyx":1266
  *                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))
+ *                                                  fst.ENCODE))
  *     if not self._mapper:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1252, __pyx_L1_error)
+    __PYX_ERR(0, 1266, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1252, __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":1253
+  /* "pywrapfst.pyx":1267
  *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                   fst.ENCODE))             # <<<<<<<<<<<<<<
+ *                                                  fst.ENCODE))             # <<<<<<<<<<<<<<
  *     if not self._mapper:
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  */
   __pyx_v_self->_mapper.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v_flags, fst::ENCODE));
 
-  /* "pywrapfst.pyx":1254
+  /* "pywrapfst.pyx":1268
  *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                   fst.ENCODE))
+ *                                                  fst.ENCODE))
  *     if not self._mapper:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1254, __pyx_L1_error)
+    __PYX_ERR(0, 1268, __pyx_L1_error)
   }
   __pyx_t_2 = ((!__pyx_v_self->_mapper) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1255
- *                                                   fst.ENCODE))
+    /* "pywrapfst.pyx":1269
+ *                                                  fst.ENCODE))
  *     if not self._mapper:
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
  * 
  *   # Python's equivalent to operator().
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1255, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1269, __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, 1255, __pyx_L1_error)
+    __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))) {
@@ -14709,7 +14715,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     }
     __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, 1255, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1269, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -14725,23 +14731,23 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
     __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, 1255, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1269, __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, 1255, __pyx_L1_error)
+    __PYX_ERR(0, 1269, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1254
+    /* "pywrapfst.pyx":1268
  *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                   fst.ENCODE))
+ *                                                  fst.ENCODE))
  *     if not self._mapper:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1247
+  /* "pywrapfst.pyx":1261
  *     return "<EncodeMapper at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
@@ -14765,7 +14771,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1259
+/* "pywrapfst.pyx":1273
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -14803,7 +14809,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, 1259, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1273, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -14814,13 +14820,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, 1259, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1273, __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, 1259, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1273, __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 */
@@ -14838,7 +14844,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__call__", 0);
 
-  /* "pywrapfst.pyx":1275
+  /* "pywrapfst.pyx":1289
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     return _init_Arc(self._mapper.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
@@ -14848,19 +14854,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, 1275, __pyx_L1_error)
+    __PYX_ERR(0, 1289, __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, 1275, __pyx_L1_error)
+    __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, 1275, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1259
+  /* "pywrapfst.pyx":1273
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -14879,7 +14885,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1279
+/* "pywrapfst.pyx":1293
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -14908,7 +14914,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1280
+  /* "pywrapfst.pyx":1294
  * 
  *   def __reduce__(self):
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -14916,20 +14922,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, 1280, __pyx_L1_error)
+  __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_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, 1280, __pyx_L1_error)
+    __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, 1280, __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_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1280, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1294, __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, 1280, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1294, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -14941,7 +14947,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1279
+  /* "pywrapfst.pyx":1293
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -14962,7 +14968,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1282
+/* "pywrapfst.pyx":1296
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -14989,7 +14995,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, 1282, __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, 1296, __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);
@@ -15005,10 +15011,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, 1282, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1296, __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, 1282, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15027,7 +15033,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":1288
+  /* "pywrapfst.pyx":1302
  *     Returns a string indicating the arc type.
  *     """
  *     return self._mapper.get().ArcType()             # <<<<<<<<<<<<<<
@@ -15036,12 +15042,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, 1288, __pyx_L1_error)
+    __PYX_ERR(0, 1302, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1282
+  /* "pywrapfst.pyx":1296
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -15082,7 +15088,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __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, 1282, __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, 1296, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15099,7 +15105,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1290
+/* "pywrapfst.pyx":1304
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15126,7 +15132,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, 1290, __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, 1304, __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);
@@ -15142,10 +15148,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, 1290, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1304, __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, 1290, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15164,7 +15170,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1296
+  /* "pywrapfst.pyx":1310
  *     Returns a string indicating the weight type.
  *     """
  *     return self._mapper.get().WeightType()             # <<<<<<<<<<<<<<
@@ -15173,12 +15179,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, 1296, __pyx_L1_error)
+    __PYX_ERR(0, 1310, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1290
+  /* "pywrapfst.pyx":1304
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15219,7 +15225,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __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, 1290, __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, 1304, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15236,7 +15242,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1298
+/* "pywrapfst.pyx":1312
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15245,14 +15251,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_13flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint8 __pyx_r;
+static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint8 __pyx_t_5;
+  uint8 __pyx_t_5;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15263,7 +15269,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(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_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1298, __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, 1312, __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);
@@ -15279,10 +15285,10 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct
         }
         __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, 1298, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1312, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1298, __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, 1312, __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;
@@ -15301,7 +15307,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":1304
+  /* "pywrapfst.pyx":1318
  *     Returns the mapper's flags.
  *     """
  *     return self._mapper.get().Flags()             # <<<<<<<<<<<<<<
@@ -15310,12 +15316,12 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1304, __pyx_L1_error)
+    __PYX_ERR(0, 1318, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1298
+  /* "pywrapfst.pyx":1312
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15356,7 +15362,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __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, 1298, __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, 1312, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15373,7 +15379,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1306
+/* "pywrapfst.pyx":1320
  *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
@@ -15382,15 +15388,15 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx_v_self, PyObject *__pyx_arg_mask); /*proto*/
-static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint64 __pyx_r;
+static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, uint64 __pyx_v_mask, int __pyx_skip_dispatch) {
+  uint64 __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;
-  __pyx_t_10basictypes_uint64 __pyx_t_6;
+  uint64 __pyx_t_6;
   __Pyx_RefNannySetupContext("properties", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15401,10 +15407,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
     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, 1306, __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, 1320, __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, 1306, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1320, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -15420,10 +15426,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
         __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, 1306, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1320, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1306, __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, 1320, __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;
@@ -15442,7 +15448,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
     #endif
   }
 
-  /* "pywrapfst.pyx":1320
+  /* "pywrapfst.pyx":1334
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._mapper.get().Properties(mask)             # <<<<<<<<<<<<<<
@@ -15451,12 +15457,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1320, __pyx_L1_error)
+    __PYX_ERR(0, 1334, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->Properties(__pyx_v_mask);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1306
+  /* "pywrapfst.pyx":1320
  *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
@@ -15482,12 +15488,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx_v_self, PyObject *__pyx_arg_mask); /*proto*/
 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) {
-  __pyx_t_10basictypes_uint64 __pyx_v_mask;
+  uint64 __pyx_v_mask;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1306, __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, 1320, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -15495,20 +15501,20 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_14properties(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((__pyx_t_10basictypes_uint64)__pyx_v_mask));
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_14properties(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((uint64)__pyx_v_mask));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, uint64 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 1306, __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, 1320, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15525,7 +15531,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1323
+/* "pywrapfst.pyx":1337
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -15560,17 +15566,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1339
+  /* "pywrapfst.pyx":1353
  *     """
  *     cdef unique_ptr[fst.EncodeMapperClass] mapper
  *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))             # <<<<<<<<<<<<<<
  *     if mapper.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1339, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":1340
+  /* "pywrapfst.pyx":1354
  *     cdef unique_ptr[fst.EncodeMapperClass] mapper
  *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
  *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15580,16 +15586,16 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1341
+    /* "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())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1341, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1355, __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, 1341, __pyx_L1_error)
+    __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))) {
@@ -15603,7 +15609,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
     }
     __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, 1341, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1355, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -15619,14 +15625,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
     __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, 1341, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1355, __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, 1341, __pyx_L1_error)
+    __PYX_ERR(0, 1355, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1340
+    /* "pywrapfst.pyx":1354
  *     cdef unique_ptr[fst.EncodeMapperClass] mapper
  *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
  *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -15635,7 +15641,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
  */
   }
 
-  /* "pywrapfst.pyx":1342
+  /* "pywrapfst.pyx":1356
  *     if mapper.get() == NULL:
  *       raise FstIOError("Read failed: {!r}".format(source))
  *     return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
@@ -15643,13 +15649,13 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
  *   @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, 1342, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1323
+  /* "pywrapfst.pyx":1337
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -15672,7 +15678,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1345
+/* "pywrapfst.pyx":1359
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -15708,7 +15714,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, 1345, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1359, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -15719,7 +15725,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, 1345, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1359, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -15738,7 +15744,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":1360
+  /* "pywrapfst.pyx":1374
  *       FstIOError: Read failed.
  *     """
  *     return _read_EncodeMapper_from_string(state)             # <<<<<<<<<<<<<<
@@ -15746,13 +15752,13 @@ 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, 1360, __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, 1374, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1345
+  /* "pywrapfst.pyx":1359
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -15771,7 +15777,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1362
+/* "pywrapfst.pyx":1376
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -15799,7 +15805,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, 1362, __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, 1376, __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);
@@ -15815,7 +15821,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, 1362, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1376, __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;
@@ -15835,7 +15841,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1375
+  /* "pywrapfst.pyx":1389
  *         FstIOError: Write failed.
  *       """
  *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
@@ -15844,22 +15850,22 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(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, 1375, __pyx_L1_error)
+    __PYX_ERR(0, 1389, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1375, __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_6 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1376
+    /* "pywrapfst.pyx":1390
  *       """
  *       if not self._mapper.get().Write(tostring(source)):
  *         raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1376, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __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, 1376, __pyx_L1_error)
+    __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))) {
@@ -15873,7 +15879,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     }
     __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, 1376, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1390, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -15889,14 +15895,14 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     __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, 1376, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1390, __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, 1376, __pyx_L1_error)
+    __PYX_ERR(0, 1390, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1375
+    /* "pywrapfst.pyx":1389
  *         FstIOError: Write failed.
  *       """
  *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
@@ -15905,7 +15911,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
  */
   }
 
-  /* "pywrapfst.pyx":1362
+  /* "pywrapfst.pyx":1376
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -15946,8 +15952,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __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, 1362, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1362, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15964,7 +15970,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1378
+/* "pywrapfst.pyx":1392
  *         raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -15992,7 +15998,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, 1378, __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, 1392, __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);
@@ -16009,10 +16015,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, 1378, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __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, 1378, __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, 1392, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16031,7 +16037,7 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1391
+  /* "pywrapfst.pyx":1405
  *       """
  *       cdef stringstream sstrm
  *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -16040,19 +16046,19 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1391, __pyx_L1_error)
+    __PYX_ERR(0, 1405, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1392
+    /* "pywrapfst.pyx":1406
  *       cdef stringstream sstrm
  *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *       return sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1406, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -16066,14 +16072,14 @@ 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, 1392, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1406, __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, 1392, __pyx_L1_error)
+    __PYX_ERR(0, 1406, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1391
+    /* "pywrapfst.pyx":1405
  *       """
  *       cdef stringstream sstrm
  *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -16082,21 +16088,21 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1393
+  /* "pywrapfst.pyx":1407
  *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")
  *       return sstrm.str()             # <<<<<<<<<<<<<<
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):
+ *   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, 1393, __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, 1407, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1378
+  /* "pywrapfst.pyx":1392
  *         raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -16138,7 +16144,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   PyObject *__pyx_t_1 = NULL;
   __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, 1378, __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, 1392, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16155,18 +16161,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1395
+/* "pywrapfst.pyx":1409
  *       return sstrm.str()
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     input_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable *__pyx_v_syms;
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -16183,7 +16188,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_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_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1395, __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, 1409, __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));
@@ -16200,11 +16205,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_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, 1395, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1409, __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__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1395, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1409, __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;
         goto __pyx_L0;
@@ -16222,79 +16227,62 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1402
+  /* "pywrapfst.pyx":1415
+ *     Returns the mapper's input symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().InputSymbols())             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1402, __pyx_L1_error)
+    __PYX_ERR(0, 1415, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1401
- *     Returns the mapper's input symbol table, or None if none is present.
- *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._mapper.get().InputSymbols())
- *     if syms == NULL:
- */
-  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_mapper.get()->InputSymbols());
-
-  /* "pywrapfst.pyx":1403
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().InputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_5 = ((__pyx_v_self->_mapper.get()->InputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1404
- *         self._mapper.get().InputSymbols())
- *     if syms == NULL:
+    /* "pywrapfst.pyx":1416
+ *     """
+ *     if self._mapper.get().InputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
  */
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1403
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().InputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1415
+ *     Returns the mapper's input symbol table, or None if none is present.
+ *     """
+ *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  */
   }
 
-  /* "pywrapfst.pyx":1405
- *     if syms == NULL:
+  /* "pywrapfst.pyx":1417
+ *     if self._mapper.get().InputSymbols() == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)             # <<<<<<<<<<<<<<
  * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):
+ *   cpdef _EncodeMapperSymbolTableView output_symbols(self):
  */
   __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, 1405, __pyx_L1_error)
+    __PYX_ERR(0, 1417, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_mapper)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1405, __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1395
+  /* "pywrapfst.pyx":1409
  *       return sstrm.str()
  * 
- *   cpdef _EncodeMapperSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     input_symbols(self)
  */
@@ -16333,7 +16321,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   PyObject *__pyx_t_1 = NULL;
   __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, 1395, __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, 1409, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16350,18 +16338,17 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1407
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+/* "pywrapfst.pyx":1419
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     output_symbols(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable *__pyx_v_syms;
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -16378,7 +16365,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_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_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __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, 1419, __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));
@@ -16395,11 +16382,11 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_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, 1407, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1419, __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__EncodeMapperSymbolTable))))) __PYX_ERR(0, 1407, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1419, __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;
         goto __pyx_L0;
@@ -16417,79 +16404,62 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *__pyx_f_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1414
+  /* "pywrapfst.pyx":1425
+ *     Returns the mapper's output symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().OutputSymbols())             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1414, __pyx_L1_error)
+    __PYX_ERR(0, 1425, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1413
- *     Returns the mapper's output symbol table, or None if none is present.
- *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *         self._mapper.get().OutputSymbols())
- *     if syms == NULL:
- */
-  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_mapper.get()->OutputSymbols());
-
-  /* "pywrapfst.pyx":1415
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_5 = ((__pyx_v_self->_mapper.get()->OutputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1416
- *         self._mapper.get().OutputSymbols())
- *     if syms == NULL:
+    /* "pywrapfst.pyx":1426
+ *     """
+ *     if self._mapper.get().OutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
  */
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1415
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *         self._mapper.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1425
+ *     Returns the mapper's output symbol table, or None if none is present.
+ *     """
+ *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  */
   }
 
-  /* "pywrapfst.pyx":1417
- *     if syms == NULL:
+  /* "pywrapfst.pyx":1427
+ *     if self._mapper.get().OutputSymbols() == NULL:
  *       return
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) 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, 1417, __pyx_L1_error)
+    __PYX_ERR(0, 1427, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable(__pyx_v_syms, __pyx_v_self->_mapper)); 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, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1407
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+  /* "pywrapfst.pyx":1419
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
- *   cpdef _EncodeMapperSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     output_symbols(self)
  */
@@ -16528,7 +16498,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   PyObject *__pyx_t_1 = NULL;
   __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, 1407, __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, 1419, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16545,112 +16515,113 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1419
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+/* "pywrapfst.pyx":1429
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     """
- *     set_input_symbols(self, syms)
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mapper.get().SetInputSymbols(NULL)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__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__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
+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) {
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("set_input_symbols", 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_set_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __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_29set_input_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))) {
-          __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_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1419, __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;
-        __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
+  int __pyx_t_1;
+  int __pyx_t_2;
+  fst::SymbolTable const *__pyx_t_3;
+  __Pyx_RefNannySetupContext("_set_input_symbols", 0);
+
+  /* "pywrapfst.pyx":1430
+ * 
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mapper.get().SetInputSymbols(NULL)
+ *       return
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == 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:
+ *       self._mapper.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
+ *       return
+ *     self._mapper.get().SetInputSymbols(syms._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)
     }
-    #endif
+    __pyx_v_self->_mapper.get()->SetInputSymbols(NULL);
+
+    /* "pywrapfst.pyx":1432
+ *     if syms is None:
+ *       self._mapper.get().SetInputSymbols(NULL)
+ *       return             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ * 
+ */
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":1430
+ * 
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mapper.get().SetInputSymbols(NULL)
+ *       return
+ */
   }
 
-  /* "pywrapfst.pyx":1428
- *       syms: A SymbolTable.
- *     """
- *     self._mapper.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1433
+ *       self._mapper.get().SetInputSymbols(NULL)
+ *       return
+ *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:
+ *   def set_input_symbols(self, _SymbolTable syms):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1428, __pyx_L1_error)
+    __PYX_ERR(0, 1433, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1428, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 1433, __pyx_L1_error)
   }
-  __pyx_v_self->_mapper.get()->SetInputSymbols(__pyx_v_syms->_table);
+  __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_v_self->_mapper.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1419
- *     return _init_EncodeMapperSymbolTable(syms, self._mapper)
+  /* "pywrapfst.pyx":1429
+ *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
- *   cpdef void set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     """
- *     set_input_symbols(self, syms)
+ *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mapper.get().SetInputSymbols(NULL)
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper._set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
+/* "pywrapfst.pyx":1435
+ *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ * 
+ *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *     """
+ *     set_input_symbols(self, syms)
+ */
+
 /* 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    Args:\n      syms: A SymbolTable.\n    ";
+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) {
   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, 1419, __pyx_L1_error)
+  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));
 
   /* function exit code */
@@ -16665,19 +16636,43 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject
 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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
+
+  /* "pywrapfst.pyx":1449
+ *       self.
+ *     """
+ *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
+ *     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)
+  }
+  ((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)
+
+  /* "pywrapfst.pyx":1450
+ *     """
+ *     self._set_input_symbols(syms)
+ *     return self             # <<<<<<<<<<<<<<
+ * 
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_set_input_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1419, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __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())
+ * 
+ *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *     """
+ *     set_input_symbols(self, syms)
+ */
+
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -16686,112 +16681,113 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1430
- *     self._mapper.get().SetInputSymbols(syms._table)
+/* "pywrapfst.pyx":1452
+ *     return self
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     """
- *     set_output_symbols(self, syms)
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mapper.get().SetOutputSymbols(NULL)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__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, int __pyx_skip_dispatch) {
+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) {
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  __Pyx_RefNannySetupContext("set_output_symbols", 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_set_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1430, __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_31set_output_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))) {
-          __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_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1430, __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;
-        __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
+  int __pyx_t_1;
+  int __pyx_t_2;
+  fst::SymbolTable const *__pyx_t_3;
+  __Pyx_RefNannySetupContext("_set_output_symbols", 0);
+
+  /* "pywrapfst.pyx":1453
+ * 
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mapper.get().SetOutputSymbols(NULL)
+ *       return
+ */
+  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == 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:
+ *       self._mapper.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
+ *       return
+ *     self._mapper.get().SetOutputSymbols(syms._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)
     }
-    #endif
-  }
+    __pyx_v_self->_mapper.get()->SetOutputSymbols(NULL);
 
-  /* "pywrapfst.pyx":1439
- *       syms: A SymbolTable.
- *     """
- *     self._mapper.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1455
+ *     if syms is None:
+ *       self._mapper.get().SetOutputSymbols(NULL)
+ *       return             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ * 
+ */
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":1453
  * 
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *     if syms is None:             # <<<<<<<<<<<<<<
+ *       self._mapper.get().SetOutputSymbols(NULL)
+ *       return
+ */
+  }
+
+  /* "pywrapfst.pyx":1456
+ *       self._mapper.get().SetOutputSymbols(NULL)
+ *       return
+ *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
+ *   def set_output_symbols(self, _SymbolTable syms):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1439, __pyx_L1_error)
+    __PYX_ERR(0, 1456, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1439, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 1456, __pyx_L1_error)
   }
-  __pyx_v_self->_mapper.get()->SetOutputSymbols(__pyx_v_syms->_table);
+  __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_v_self->_mapper.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1430
- *     self._mapper.get().SetInputSymbols(syms._table)
+  /* "pywrapfst.pyx":1452
+ *     return self
  * 
- *   cpdef void set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     """
- *     set_output_symbols(self, syms)
+ *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *     if syms is None:
+ *       self._mapper.get().SetOutputSymbols(NULL)
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.EncodeMapper._set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
+/* "pywrapfst.pyx":1458
+ *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ * 
+ *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *     """
+ *     set_output_symbols(self, syms)
+ */
+
 /* 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    Args:\n      syms: A SymbolTable.\n    ";
+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) {
   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, 1430, __pyx_L1_error)
+  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));
 
   /* function exit code */
@@ -16806,19 +16802,43 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObjec
 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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
+
+  /* "pywrapfst.pyx":1472
+ *       self.
+ *     """
+ *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
+ *     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)
+  }
+  ((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)
+
+  /* "pywrapfst.pyx":1473
+ *     """
+ *     self._set_output_symbols(syms)
+ *     return self             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1430, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1430, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
+  /* "pywrapfst.pyx":1458
+ *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ * 
+ *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *     """
+ *     set_output_symbols(self, syms)
+ */
+
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -16827,35 +16847,35 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1442
+/* "pywrapfst.pyx":1476
  * 
  * 
- * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):             # <<<<<<<<<<<<<<
+ * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)
  */
 
-static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(fst::script::EncodeMapperClass *__pyx_v_mapper) {
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_t_9pywrapfst_EncodeMapperClass_ptr __pyx_v_mapper) {
   struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_result = 0;
   struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("_init_EncodeMapper", 0);
 
-  /* "pywrapfst.pyx":1443
+  /* "pywrapfst.pyx":1477
  * 
- * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+ * 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, 1443, __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, 1477, __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":1444
- * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+  /* "pywrapfst.pyx":1478
+ * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)             # <<<<<<<<<<<<<<
  *   return result
@@ -16863,11 +16883,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, 1444, __pyx_L1_error)
+    __PYX_ERR(0, 1478, __pyx_L1_error)
   }
   __pyx_v_result->_mapper.reset(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1445
+  /* "pywrapfst.pyx":1479
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)
  *   return result             # <<<<<<<<<<<<<<
@@ -16879,10 +16899,10 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1442
+  /* "pywrapfst.pyx":1476
  * 
  * 
- * cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):             # <<<<<<<<<<<<<<
+ * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)
  */
@@ -16899,7 +16919,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1448
+/* "pywrapfst.pyx":1482
  * 
  * 
  * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
@@ -16920,17 +16940,17 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
 
-  /* "pywrapfst.pyx":1450
+  /* "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>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1450, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":1452
+  /* "pywrapfst.pyx":1486
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.EncodeMapperClass] mapper
  *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -16939,7 +16959,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  */
   __pyx_v_mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1453
+  /* "pywrapfst.pyx":1487
  *   cdef unique_ptr[fst.EncodeMapperClass] mapper
  *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -16949,14 +16969,14 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
   __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1454
+    /* "pywrapfst.pyx":1488
  *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if mapper.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
  *   return _init_EncodeMapper(mapper.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1454, __pyx_L1_error)
+    __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))) {
@@ -16970,14 +16990,14 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
     }
     __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, 1454, __pyx_L1_error)
+    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_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1454, __pyx_L1_error)
+    __PYX_ERR(0, 1488, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1453
+    /* "pywrapfst.pyx":1487
  *   cdef unique_ptr[fst.EncodeMapperClass] mapper
  *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
@@ -16986,7 +17006,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  */
   }
 
-  /* "pywrapfst.pyx":1455
+  /* "pywrapfst.pyx":1489
  *   if mapper.get() == NULL:
  *     raise FstIOError("Read failed")
  *   return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
@@ -16994,13 +17014,13 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
  * 
  */
   __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, 1455, __pyx_L1_error)
+  __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1448
+  /* "pywrapfst.pyx":1482
  * 
  * 
  * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
@@ -17040,7 +17060,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
   PyObject *__pyx_t_1 = NULL;
   __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, 1448, __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, 1482, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17057,7 +17077,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1481
+/* "pywrapfst.pyx":1515
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17065,7 +17085,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
  *                             stdin=subprocess.PIPE,
  */
 
-static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const &__pyx_v_dot) {
+static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &__pyx_v_dot) {
   PyObject *__pyx_v_proc = NULL;
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
@@ -17076,77 +17096,77 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   std::string __pyx_t_5;
   __Pyx_RefNannySetupContext("_local_render_svg", 0);
 
-  /* "pywrapfst.pyx":1482
+  /* "pywrapfst.pyx":1516
  *   @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, 1482, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1516, __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, 1482, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1483
+  /* "pywrapfst.pyx":1517
  *   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, 1483, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1517, __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, 1483, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1517, __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, 1483, __pyx_L1_error)
+  __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_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, 1483, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1517, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":1484
+  /* "pywrapfst.pyx":1518
  *     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, 1484, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1518, __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, 1484, __pyx_L1_error)
+  __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_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, 1483, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1517, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1482
+  /* "pywrapfst.pyx":1516
  *   @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, 1482, __pyx_L1_error)
+  __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_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":1485
+  /* "pywrapfst.pyx":1519
  *                             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, 1485, __pyx_L1_error)
+  __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_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, 1485, __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, 1519, __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, 1485, __pyx_L1_error)
+  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1519, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -17162,22 +17182,22 @@ static std::string __pyx_f_9pywrapfst_4_Fst__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, 1485, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1519, __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, 1485, __pyx_L1_error)
+    __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, 1485, __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_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, 1485, __pyx_L1_error)
+  __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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1481
+  /* "pywrapfst.pyx":1515
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17191,7 +17211,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst._local_render_svg", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst._local_render_svg", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_proc);
@@ -17199,7 +17219,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1487
+/* "pywrapfst.pyx":1521
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17208,20 +17228,20 @@ static std::string __pyx_f_9pywrapfst_4_Fst__local_render_svg(std::string const
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst__repr_svg_[] = "IPython notebook magic to produce an SVG of the FST using GraphViz.\n\n    This method produces an SVG of the internal graph. Users wishing to create\n    publication-quality graphs should instead use the method `draw`, which\n    exposes additional parameters.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst__repr_svg_[] = "IPython notebook magic to produce an SVG of the FST using GraphViz.\n\n    This method produces an SVG of the internal graph. Users wishing to create\n    publication-quality graphs should instead use the method `draw`, which\n    exposes additional parameters.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_1_repr_svg_(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_repr_svg_ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst__repr_svg_(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst__repr_svg_(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   std::stringstream __pyx_v_sstrm;
   bool __pyx_v_acceptor;
   PyObject *__pyx_v_e = NULL;
@@ -17248,7 +17268,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_19 = NULL;
   __Pyx_RefNannySetupContext("_repr_svg_", 0);
 
-  /* "pywrapfst.pyx":1495
+  /* "pywrapfst.pyx":1529
  *     """
  *     cdef stringstream sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
@@ -17257,10 +17277,10 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1495, __pyx_L1_error)
+    __PYX_ERR(0, 1529, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1496
+  /* "pywrapfst.pyx":1530
  *     cdef stringstream sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)             # <<<<<<<<<<<<<<
@@ -17269,7 +17289,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   __pyx_v_acceptor = (__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor);
 
-  /* "pywrapfst.pyx":1497
+  /* "pywrapfst.pyx":1531
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
@@ -17278,14 +17298,14 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1497, __pyx_L1_error)
+    __PYX_ERR(0, 1531, __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, 1497, __pyx_L1_error)
+    __PYX_ERR(0, 1531, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1498
+  /* "pywrapfst.pyx":1532
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
  *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,             # <<<<<<<<<<<<<<
@@ -17294,10 +17314,10 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1498, __pyx_L1_error)
+    __PYX_ERR(0, 1532, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1497
+  /* "pywrapfst.pyx":1531
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
  *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
@@ -17306,11 +17326,11 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
   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);
 
-  /* "pywrapfst.pyx":1501
+  /* "pywrapfst.pyx":1535
  *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
- *       return _Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(sstrm.str())
  *     except Exception as e:
  */
   {
@@ -17322,42 +17342,42 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":1502
+      /* "pywrapfst.pyx":1536
  *              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_4_Fst__local_render_svg(__pyx_v_sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1502, __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, 1536, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_r = __pyx_t_4;
       __pyx_t_4 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":1501
+      /* "pywrapfst.pyx":1535
  *              True, False, 0.4, 0.25, 14, 5, b"g", False, 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":1503
+    /* "pywrapfst.pyx":1537
  *     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_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, 1503, __pyx_L5_except_error)
+      __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)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_GOTREF(__pyx_t_7);
@@ -17365,16 +17385,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
       __pyx_v_e = __pyx_t_6;
       /*try:*/ {
 
-        /* "pywrapfst.pyx":1504
- *       return _Fst._local_render_svg(sstrm.str())
+        /* "pywrapfst.pyx":1538
+ *       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, 1504, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1538, __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, 1504, __pyx_L14_error)
+        __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_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_9 = NULL;
@@ -17392,7 +17412,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         #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, 1504, __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, 1538, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
@@ -17400,13 +17420,13 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         #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, 1504, __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, 1538, __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, 1504, __pyx_L14_error)
+          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1538, __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;
@@ -17417,7 +17437,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
           __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, 1504, __pyx_L14_error)
+          __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_GOTREF(__pyx_t_8);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         }
@@ -17425,9 +17445,9 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
 
-      /* "pywrapfst.pyx":1503
+      /* "pywrapfst.pyx":1537
  *     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)
  * 
@@ -17484,11 +17504,11 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":1501
+    /* "pywrapfst.pyx":1535
  *              True, False, 0.4, 0.25, 14, 5, b"g", False, 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);
@@ -17509,7 +17529,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "pywrapfst.pyx":1487
+  /* "pywrapfst.pyx":1521
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17528,7 +17548,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_t_9);
   __Pyx_XDECREF(__pyx_t_10);
   __Pyx_XDECREF(__pyx_t_11);
-  __Pyx_AddTraceback("pywrapfst._Fst._repr_svg_", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst._repr_svg_", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_e);
@@ -17537,7 +17557,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1506
+/* "pywrapfst.pyx":1540
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -17546,22 +17566,22 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst__repr_svg_(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_4_Fst_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_4_Fst_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static int __pyx_pw_9pywrapfst_3Fst_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_9pywrapfst_3Fst_3__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_4_Fst_2__init__(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_2__init__(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static int __pyx_pf_9pywrapfst_3Fst_2__init__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -17572,28 +17592,28 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1507
+  /* "pywrapfst.pyx":1541
  * 
  *   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, 1507, __pyx_L1_error)
+  __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":1508
+  /* "pywrapfst.pyx":1542
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(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, 1508, __pyx_L1_error)
+  __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, 1508, __pyx_L1_error)
+  __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, 1508, __pyx_L1_error)
+  __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;
@@ -17609,7 +17629,7 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   __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, 1508, __pyx_L1_error)
+  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;
@@ -17625,14 +17645,14 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   __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, 1507, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __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, 1507, __pyx_L1_error)
+  __PYX_ERR(0, 1541, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1506
+  /* "pywrapfst.pyx":1540
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -17648,13 +17668,13 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
   __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_AddTraceback("pywrapfst.Fst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1513
+/* "pywrapfst.pyx":1547
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -17663,19 +17683,19 @@ static int __pyx_pf_9pywrapfst_4_Fst_2__init__(struct __pyx_obj_9pywrapfst__Fst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_3Fst_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_4_Fst_4__reduce__(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_4__reduce__(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -17683,7 +17703,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1514
+  /* "pywrapfst.pyx":1548
  * 
  *   def __reduce__(self):
  *     return (_read_Fst_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -17691,20 +17711,20 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
  *   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, 1514, __pyx_L1_error)
+  __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_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, 1514, __pyx_L1_error)
+    __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, 1514, __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_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1514, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1548, __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, 1514, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1548, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -17716,7 +17736,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1513
+  /* "pywrapfst.pyx":1547
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -17729,7 +17749,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._Fst.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -17737,7 +17757,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1516
+/* "pywrapfst.pyx":1550
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -17746,19 +17766,19 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_4__reduce__(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_7__repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_7__repr__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_7__repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_3Fst_7__repr__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_6__repr__(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_6__repr__(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -17770,7 +17790,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1517
+  /* "pywrapfst.pyx":1551
  * 
  *   def __repr__(self):
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))             # <<<<<<<<<<<<<<
@@ -17778,15 +17798,15 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
  *   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, 1517, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "fst_type");
-    __PYX_ERR(0, 1517, __pyx_L1_error)
+    __PYX_ERR(0, 1551, __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, 1517, __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, 1517, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -17803,7 +17823,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   #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, 1517, __pyx_L1_error)
+    __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;
@@ -17813,7 +17833,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   #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, 1517, __pyx_L1_error)
+    __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;
@@ -17821,7 +17841,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1517, __pyx_L1_error)
+    __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;
@@ -17832,7 +17852,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
     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, 1517, __pyx_L1_error)
+    __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;
   }
@@ -17841,7 +17861,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1516
+  /* "pywrapfst.pyx":1550
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -17857,7 +17877,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   __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_AddTraceback("pywrapfst.Fst.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -17865,63 +17885,65 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_6__repr__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1519
+/* "pywrapfst.pyx":1553
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
- *     return self.text()
+ *     return self.print()
  * 
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_9__str__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_9__str__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_9__str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_3Fst_9__str__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_8__str__(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_8__str__(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  std::string __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":1520
+  /* "pywrapfst.pyx":1554
  * 
  *   def __str__(self):
- *     return self.text()             # <<<<<<<<<<<<<<
+ *     return self.print()             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "text");
-    __PYX_ERR(0, 1520, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "print");
+    __PYX_ERR(0, 1554, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst__Fst *)__pyx_v_self->__pyx_vtab)->text(__pyx_v_self, 0, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1520, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __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_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1519
+  /* "pywrapfst.pyx":1553
  *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
- *     return self.text()
+ *     return self.print()
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_AddTraceback("pywrapfst.Fst.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -17929,16 +17951,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_8__str__(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1522
- *     return self.text()
+/* "pywrapfst.pyx":1556
+ *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
  *     arc_type(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -17956,9 +17978,9 @@ static std::string __pyx_f_9pywrapfst_4_Fst_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, 1522, __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, 1556, __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_4_Fst_11arc_type)) {
+      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);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -17972,10 +17994,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_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, 1522, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1556, __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, 1522, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -17994,7 +18016,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1528
+  /* "pywrapfst.pyx":1562
  *     Returns a string indicating the arc type.
  *     """
  *     return self._fst.get().ArcType()             # <<<<<<<<<<<<<<
@@ -18003,13 +18025,13 @@ static std::string __pyx_f_9pywrapfst_4_Fst_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, 1528, __pyx_L1_error)
+    __PYX_ERR(0, 1562, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1522
- *     return self.text()
+  /* "pywrapfst.pyx":1556
+ *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -18022,7 +18044,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -18030,26 +18052,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_arc_type(struct __pyx_obj_9pywrapfst
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_10arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_10arc_type[] = "\n    arc_type(self)\n\n    Returns a string indicating the arc type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_11arc_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arc_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_10arc_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_10arc_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1522, __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, 1556, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18058,7 +18080,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfs
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.arc_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -18066,7 +18088,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1530
+/* "pywrapfst.pyx":1564
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18074,8 +18096,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_10arc_type(struct __pyx_obj_9pywrapfs
  *     arcs(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*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) {
   struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -18093,11 +18115,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(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_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1530, __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, 1564, __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_4_Fst_13arcs)) {
+      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, 1530, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1564, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18113,10 +18135,10 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
         __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, 1530, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1564, __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, 1530, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1564, __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;
@@ -18135,17 +18157,17 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
     #endif
   }
 
-  /* "pywrapfst.pyx":1542
+  /* "pywrapfst.pyx":1576
  *       An ArcIterator.
  *     """
  *     return ArcIterator(self, state)             # <<<<<<<<<<<<<<
  * 
- *   cpdef _Fst copy(self):
+ *   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, 1542, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1542, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -18153,14 +18175,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
   __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, 1542, __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, 1576, __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":1530
+  /* "pywrapfst.pyx":1564
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18175,7 +18197,7 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -18184,36 +18206,36 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_4_Fst_arcs(st
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1530, __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, 1564, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_12arcs(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_12arcs(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1530, __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, 1564, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18222,7 +18244,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__F
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -18230,17 +18252,17 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_12arcs(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1544
+/* "pywrapfst.pyx":1578
  *     return ArcIterator(self, state)
  * 
- *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
  *     """
  *     copy(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -18256,9 +18278,9 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(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_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1544, __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, 1578, __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_4_Fst_15copy)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_15copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -18273,11 +18295,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
         }
         __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, 1544, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1578, __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, 1544, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 1578, __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;
         goto __pyx_L0;
@@ -18295,7 +18317,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
     #endif
   }
 
-  /* "pywrapfst.pyx":1550
+  /* "pywrapfst.pyx":1584
  *     Makes a copy of the FST.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -18305,18 +18327,18 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
   __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, 1550, __pyx_L1_error)
+    __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, 1550, __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1544
+  /* "pywrapfst.pyx":1578
  *     return ArcIterator(self, state)
  * 
- *   cpdef _Fst copy(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
  *     """
  *     copy(self)
  */
@@ -18327,7 +18349,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._Fst.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -18336,26 +18358,26 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_4_Fst_copy(struct __
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_14copy[] = "\n    copy(self)\n\n    Makes a copy of the FST.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_14copy[] = "\n    copy(self)\n\n    Makes a copy of the FST.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_15copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("copy (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_14copy(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_14copy(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1544, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18364,7 +18386,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__F
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -18372,7 +18394,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1552
+/* "pywrapfst.pyx":1586
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18380,10 +18402,10 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_14copy(struct __pyx_obj_9pywrapfst__F
  *                   _SymbolTable isymbols=None,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args) {
+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":1554
+  /* "pywrapfst.pyx":1588
  *   cpdef void draw(self,
  *                   source,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -18392,7 +18414,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1555
+  /* "pywrapfst.pyx":1589
  *                   source,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -18401,7 +18423,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1556
+  /* "pywrapfst.pyx":1590
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
  *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -18410,7 +18432,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":1557
+  /* "pywrapfst.pyx":1591
  *                   _SymbolTable osymbols=None,
  *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -18422,7 +18444,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   double __pyx_v_width = ((double)8.5);
   double __pyx_v_height = ((double)11.0);
 
-  /* "pywrapfst.pyx":1561
+  /* "pywrapfst.pyx":1595
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -18431,7 +18453,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   bool __pyx_v_portrait = ((bool)0);
 
-  /* "pywrapfst.pyx":1562
+  /* "pywrapfst.pyx":1596
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -18441,14 +18463,14 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   bool __pyx_v_vertical = ((bool)0);
   double __pyx_v_ranksep = ((double)0.4);
   double __pyx_v_nodesep = ((double)0.25);
-  __pyx_t_10basictypes_int32 __pyx_v_fontsize = ((__pyx_t_10basictypes_int32)14);
-  __pyx_t_10basictypes_int32 __pyx_v_precision = ((__pyx_t_10basictypes_int32)5);
+  int32 __pyx_v_fontsize = ((int32)14);
+  int32 __pyx_v_precision = ((int32)5);
   PyObject *__pyx_v_float_format = ((PyObject *)__pyx_n_b_g);
 
-  /* "pywrapfst.pyx":1568
+  /* "pywrapfst.pyx":1602
  *                   int32 precision=5,
  *                   float_format=b"g",
- *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
+ *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
  *     """
  *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
  */
@@ -18457,7 +18479,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   std::unique_ptr<std::ostream>  __pyx_v_fstrm;
   fst::SymbolTable const *__pyx_v__isymbols;
   fst::SymbolTable const *__pyx_v__osymbols;
-  fst::SymbolTable *__pyx_v__ssymbols;
+  fst::SymbolTable const *__pyx_v__ssymbols;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -18478,7 +18500,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   std::string __pyx_t_17;
   int __pyx_t_18;
   int __pyx_t_19;
-  fst::SymbolTable *__pyx_t_20;
+  fst::SymbolTable const *__pyx_t_20;
   std::string __pyx_t_21;
   __Pyx_RefNannySetupContext("draw", 0);
   if (__pyx_optional_args) {
@@ -18529,7 +18551,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":1552
+  /* "pywrapfst.pyx":1586
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18545,28 +18567,28 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(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_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1552, __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, 1586, __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_4_Fst_17draw)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1552, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
-        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1552, __pyx_L1_error)
+        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1586, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1552, __pyx_L1_error)
+        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1586, __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, 1552, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1586, __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, 1552, __pyx_L1_error)
+        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1586, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1552, __pyx_L1_error)
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1586, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1552, __pyx_L1_error)
+        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1586, __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, 1552, __pyx_L1_error)
+        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1586, __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, 1552, __pyx_L1_error)
+        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1586, __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, 1552, __pyx_L1_error)
+        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1586, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_13 = __pyx_t_1; __pyx_t_14 = NULL;
@@ -18584,7 +18606,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
         #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, 1552, __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, 1586, __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;
@@ -18602,7 +18624,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
         #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, 1552, __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, 1586, __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;
@@ -18618,7 +18640,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
         } else
         #endif
         {
-          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1552, __pyx_L1_error)
+          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1586, __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;
@@ -18671,7 +18693,7 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
           __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, 1552, __pyx_L1_error)
+          __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_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         }
@@ -18693,17 +18715,17 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1600
+  /* "pywrapfst.pyx":1634
  *       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))
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1600, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":1602
+  /* "pywrapfst.pyx":1636
  *     cdef string source_string = tostring(source)
  *     cdef unique_ptr[ostream] fstrm
  *     fstrm.reset(new ofstream(source_string))             # <<<<<<<<<<<<<<
@@ -18712,183 +18734,183 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   __pyx_v_fstrm.reset(new std::ofstream(__pyx_v_source_string));
 
-  /* "pywrapfst.pyx":1603
+  /* "pywrapfst.pyx":1637
  *     cdef unique_ptr[ostream] fstrm
  *     fstrm.reset(new ofstream(source_string))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
  *     if isymbols is not None:
- *        _isymbols = isymbols._table
+ *        _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, 1603, __pyx_L1_error)
+    __PYX_ERR(0, 1637, __pyx_L1_error)
   }
   __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1604
+  /* "pywrapfst.pyx":1638
  *     fstrm.reset(new ofstream(source_string))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *        _isymbols = isymbols._table
+ *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
   __pyx_t_18 = (((PyObject *)__pyx_v_isymbols) != Py_None);
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1605
+    /* "pywrapfst.pyx":1639
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
- *        _isymbols = isymbols._table             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1605, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 1639, __pyx_L1_error)
     }
-    __pyx_t_20 = __pyx_v_isymbols->_table;
+    __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_v__isymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1604
+    /* "pywrapfst.pyx":1638
  *     fstrm.reset(new ofstream(source_string))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *        _isymbols = isymbols._table
+ *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
   }
 
-  /* "pywrapfst.pyx":1606
+  /* "pywrapfst.pyx":1640
  *     if isymbols is not None:
- *        _isymbols = isymbols._table
+ *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
  *     if osymbols is not None:
- *        _osymbols = osymbols._table
+ *        _osymbols = osymbols._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, 1606, __pyx_L1_error)
+    __PYX_ERR(0, 1640, __pyx_L1_error)
   }
   __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1607
- *        _isymbols = isymbols._table
+  /* "pywrapfst.pyx":1641
+ *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  */
   __pyx_t_19 = (((PyObject *)__pyx_v_osymbols) != Py_None);
   __pyx_t_18 = (__pyx_t_19 != 0);
   if (__pyx_t_18) {
 
-    /* "pywrapfst.pyx":1608
+    /* "pywrapfst.pyx":1642
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
- *        _osymbols = osymbols._table             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *_ssymbols = NULL
+ *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1608, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 1642, __pyx_L1_error)
     }
-    __pyx_t_20 = __pyx_v_osymbols->_table;
+    __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_v__osymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1607
- *        _isymbols = isymbols._table
+    /* "pywrapfst.pyx":1641
+ *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":1609
+  /* "pywrapfst.pyx":1643
  *     if osymbols is not None:
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
  *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
  */
   __pyx_v__ssymbols = NULL;
 
-  /* "pywrapfst.pyx":1610
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
+  /* "pywrapfst.pyx":1644
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),
  */
   __pyx_t_18 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1611
- *     cdef fst.SymbolTable *_ssymbols = NULL
+    /* "pywrapfst.pyx":1645
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     fst.Draw(deref(self._fst),
  *         _isymbols,
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1611, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 1645, __pyx_L1_error)
     }
-    __pyx_t_20 = __pyx_v_ssymbols->_table;
+    __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_v__ssymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1610
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
+    /* "pywrapfst.pyx":1644
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),
  */
   }
 
-  /* "pywrapfst.pyx":1612
+  /* "pywrapfst.pyx":1646
  *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
  *         _isymbols,
  *         _osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1612, __pyx_L1_error)
+    __PYX_ERR(0, 1646, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1617
+  /* "pywrapfst.pyx":1651
  *         _ssymbols,
  *         acceptor,
  *         tostring(title),             # <<<<<<<<<<<<<<
  *         width,
  *         height,
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1617, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1651, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1626
+  /* "pywrapfst.pyx":1660
  *         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, 1626, __pyx_L1_error)
+  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1660, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1612
+  /* "pywrapfst.pyx":1646
  *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
  *         _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);
 
-  /* "pywrapfst.pyx":1552
+  /* "pywrapfst.pyx":1586
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -18914,15 +18936,15 @@ static void __pyx_f_9pywrapfst_4_Fst_draw(struct __pyx_obj_9pywrapfst__Fst *__py
   __Pyx_XDECREF(__pyx_t_13);
   __Pyx_XDECREF(__pyx_t_14);
   __Pyx_XDECREF(__pyx_t_16);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst.Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+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;
@@ -18935,8 +18957,8 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
   bool __pyx_v_vertical;
   double __pyx_v_ranksep;
   double __pyx_v_nodesep;
-  __pyx_t_10basictypes_int32 __pyx_v_fontsize;
-  __pyx_t_10basictypes_int32 __pyx_v_precision;
+  int32 __pyx_v_fontsize;
+  int32 __pyx_v_precision;
   PyObject *__pyx_v_float_format = 0;
   bool __pyx_v_show_weight_one;
   PyObject *__pyx_r = 0;
@@ -18946,7 +18968,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
     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":1554
+    /* "pywrapfst.pyx":1588
  *   cpdef void draw(self,
  *                   source,
  *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -18955,7 +18977,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
  */
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1555
+    /* "pywrapfst.pyx":1589
  *                   source,
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -18964,7 +18986,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":1556
+    /* "pywrapfst.pyx":1590
  *                   _SymbolTable isymbols=None,
  *                   _SymbolTable osymbols=None,
  *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -19110,7 +19132,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1552, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1586, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -19154,10 +19176,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)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, 1557, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1591, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1557
+      /* "pywrapfst.pyx":1591
  *                   _SymbolTable osymbols=None,
  *                   _SymbolTable ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -19168,20 +19190,20 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
     }
     __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, 1559, __pyx_L3_error)
+      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1593, __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, 1560, __pyx_L3_error)
+      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1594, __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, 1561, __pyx_L3_error)
+      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1595, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1561
+      /* "pywrapfst.pyx":1595
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -19191,10 +19213,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
       __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, 1562, __pyx_L3_error)
+      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1596, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1562
+      /* "pywrapfst.pyx":1596
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -19204,34 +19226,34 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
       __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, 1563, __pyx_L3_error)
+      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1597, __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, 1564, __pyx_L3_error)
+      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1598, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1565, __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, 1599, __pyx_L3_error)
     } else {
-      __pyx_v_fontsize = ((__pyx_t_10basictypes_int32)14);
+      __pyx_v_fontsize = ((int32)14);
     }
     if (values[13]) {
-      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1566, __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, 1600, __pyx_L3_error)
     } else {
-      __pyx_v_precision = ((__pyx_t_10basictypes_int32)5);
+      __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, 1568, __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, 1602, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1568
+      /* "pywrapfst.pyx":1602
  *                   int32 precision=5,
  *                   float_format=b"g",
- *                   bool show_weight_one=False):             # <<<<<<<<<<<<<<
+ *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
  *     """
  *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
  */
@@ -19240,18 +19262,18 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1552, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1586, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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, 1554, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1555, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1556, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_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);
+  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)
+  __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":1552
+  /* "pywrapfst.pyx":1586
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
@@ -19268,10 +19290,10 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_17draw(PyObject *__pyx_v_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_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, __pyx_t_10basictypes_int32 __pyx_v_fontsize, __pyx_t_10basictypes_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__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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_4_Fst_draw __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_3Fst_draw __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("draw", 0);
   __Pyx_XDECREF(__pyx_r);
@@ -19291,8 +19313,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
   __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); 
-  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1552, __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, 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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19301,7 +19323,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -19309,7 +19331,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1631
+/* "pywrapfst.pyx":1665
  *         source_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -19317,8 +19339,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_16draw(struct __pyx_obj_9pywrapfst__F
  *     final(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+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_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -19338,11 +19360,11 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_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, 1631, __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, 1665, __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_4_Fst_19final)) {
+      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, 1631, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1665, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19358,10 +19380,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_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, 1631, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1665, __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, 1631, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1665, __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;
@@ -19380,19 +19402,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":1646
+  /* "pywrapfst.pyx":1680
  *       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():
  */
-  __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, 1646, __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, 1680, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1647
+  /* "pywrapfst.pyx":1681
  *     """
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
@@ -19401,15 +19423,15 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 1647, __pyx_L1_error)
+    __PYX_ERR(0, 1681, __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, 1647, __pyx_L1_error)
+    __PYX_ERR(0, 1681, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
 
-  /* "pywrapfst.pyx":1648
+  /* "pywrapfst.pyx":1682
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():             # <<<<<<<<<<<<<<
@@ -19418,19 +19440,19 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 1648, __pyx_L1_error)
+    __PYX_ERR(0, 1682, __pyx_L1_error)
   }
   __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":1649
+    /* "pywrapfst.pyx":1683
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1649, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1683, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19444,14 +19466,14 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_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, 1649, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1683, __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, 1649, __pyx_L1_error)
+    __PYX_ERR(0, 1683, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1648
+    /* "pywrapfst.pyx":1682
  *     cdef Weight weight = Weight.__new__(Weight)
  *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
  *     if not weight.member():             # <<<<<<<<<<<<<<
@@ -19460,7 +19482,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
  */
   }
 
-  /* "pywrapfst.pyx":1650
+  /* "pywrapfst.pyx":1684
  *     if not weight.member():
  *       raise FstIndexError("State index out of range")
  *     return weight             # <<<<<<<<<<<<<<
@@ -19472,7 +19494,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
   __pyx_r = __pyx_v_weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1631
+  /* "pywrapfst.pyx":1665
  *         source_string)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
@@ -19487,7 +19509,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XDECREF((PyObject *)__pyx_v_weight);
@@ -19497,36 +19519,36 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_4_Fst_final(struct
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1631, __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, 1665, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_18final(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_18final(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("final", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1631, __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, 1665, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19535,7 +19557,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -19543,7 +19565,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1652
+/* "pywrapfst.pyx":1686
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -19551,8 +19573,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_18final(struct __pyx_obj_9pywrapfst__
  *     fst_type(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -19570,9 +19592,9 @@ static std::string __pyx_f_9pywrapfst_4_Fst_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, 1652, __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, 1686, __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_4_Fst_21fst_type)) {
+      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);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -19586,10 +19608,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_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, 1652, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1686, __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, 1652, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19608,21 +19630,21 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1658
+  /* "pywrapfst.pyx":1692
  *     Returns a string indicating the FST type.
  *     """
  *     return self._fst.get().FstType()             # <<<<<<<<<<<<<<
  * 
- *   cpdef _FstSymbolTable input_symbols(self):
+ *   cpdef _FstSymbolTableView input_symbols(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1658, __pyx_L1_error)
+    __PYX_ERR(0, 1692, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->FstType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1652
+  /* "pywrapfst.pyx":1686
  *     return weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
@@ -19636,7 +19658,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.fst_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.fst_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -19644,26 +19666,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_fst_type(struct __pyx_obj_9pywrapfst
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_20fst_type[] = "\n    fst_type(self)\n\n    Returns a string indicating the FST type.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_20fst_type[] = "\n    fst_type(self)\n\n    Returns a string indicating the FST type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_21fst_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("fst_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_20fst_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_20fst_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("fst_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1652, __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, 1686, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19672,7 +19694,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfs
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.fst_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.fst_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -19680,18 +19702,18 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_20fst_type(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1660
+/* "pywrapfst.pyx":1694
  *     return self._fst.get().FstType()
  * 
- *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     input_symbols(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable *__pyx_v_syms;
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_r = NULL;
+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;
   PyObject *__pyx_t_2 = NULL;
@@ -19708,9 +19730,9 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     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, 1660, __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, 1694, __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_4_Fst_23input_symbols)) {
+      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));
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -19725,11 +19747,11 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
         }
         __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, 1660, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1694, __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__FstSymbolTable))))) __PYX_ERR(0, 1660, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1694, __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;
         goto __pyx_L0;
@@ -19747,79 +19769,71 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
     #endif
   }
 
-  /* "pywrapfst.pyx":1667
+  /* "pywrapfst.pyx":1700
+ *     Returns the FST's input symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().InputSymbols())             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
  *     if syms == NULL:
  *       return
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1667, __pyx_L1_error)
+    __PYX_ERR(0, 1700, __pyx_L1_error)
   }
+  __pyx_v_syms = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1666
- *     Returns the FST's input symbol table, or None if none is present.
+  /* "pywrapfst.pyx":1701
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *       self._fst.get().InputSymbols())
- *     if syms == NULL:
- */
-  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->InputSymbols());
-
-  /* "pywrapfst.pyx":1668
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().InputSymbols())
+ *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(syms, self._fst)
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  */
   __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1669
- *       self._fst.get().InputSymbols())
+    /* "pywrapfst.pyx":1702
+ *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
- *     return _init_FstSymbolTable(syms, self._fst)
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  */
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1668
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().InputSymbols())
+    /* "pywrapfst.pyx":1701
+ *     """
+ *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_FstSymbolTable(syms, self._fst)
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  */
   }
 
-  /* "pywrapfst.pyx":1670
+  /* "pywrapfst.pyx":1703
  *     if syms == NULL:
  *       return
- *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)             # <<<<<<<<<<<<<<
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:
  */
   __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, 1670, __pyx_L1_error)
+    __PYX_ERR(0, 1703, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(__pyx_v_syms, __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1670, __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1660
+  /* "pywrapfst.pyx":1694
  *     return self._fst.get().FstType()
  * 
- *   cpdef _FstSymbolTable input_symbols(self):             # <<<<<<<<<<<<<<
+ *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
  *     input_symbols(self)
  */
@@ -19830,7 +19844,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._Fst.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -19839,26 +19853,26 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_inp
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_22input_symbols[] = "\n    input_symbols(self)\n\n    Returns the FST's input symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_22input_symbols[] = "\n    input_symbols(self)\n\n    Returns the FST's input symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("input_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_22input_symbols(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_22input_symbols(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1660, __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, 1694, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19867,7 +19881,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -19875,16 +19889,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_22input_symbols(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1672
- *     return _init_FstSymbolTable(syms, self._fst)
+/* "pywrapfst.pyx":1705
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
  *     num_arcs(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+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_r;
   __Pyx_RefNannyDeclarations
@@ -19905,10 +19919,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_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, 1672, __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, 1705, __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_4_Fst_25num_arcs)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1672, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19924,10 +19938,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_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, 1672, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1705, __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, 1672, __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, 1705, __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;
@@ -19946,7 +19960,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1687
+  /* "pywrapfst.pyx":1720
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
@@ -19955,11 +19969,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(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, 1687, __pyx_L1_error)
+    __PYX_ERR(0, 1720, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1688
+  /* "pywrapfst.pyx":1721
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -19969,14 +19983,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1689
+    /* "pywrapfst.pyx":1722
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1689, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1722, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19990,14 +20004,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_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, 1689, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1722, __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, 1689, __pyx_L1_error)
+    __PYX_ERR(0, 1722, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1688
+    /* "pywrapfst.pyx":1721
  *     """
  *     cdef size_t result = self._fst.get().NumArcs(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20006,7 +20020,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
  */
   }
 
-  /* "pywrapfst.pyx":1690
+  /* "pywrapfst.pyx":1723
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -20016,8 +20030,8 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1672
- *     return _init_FstSymbolTable(syms, self._fst)
+  /* "pywrapfst.pyx":1705
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -20031,7 +20045,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -20039,38 +20053,38 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_arcs(struct __pyx_obj_9pywrapfst__Fst
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1672, __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, 1705, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_24num_arcs(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_24num_arcs(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1672, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1672, __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, 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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20079,7 +20093,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfs
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -20087,7 +20101,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1692
+/* "pywrapfst.pyx":1725
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20095,8 +20109,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_24num_arcs(struct __pyx_obj_9pywrapfs
  *     num_input_epsilons(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+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_r;
   __Pyx_RefNannyDeclarations
@@ -20117,10 +20131,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_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_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1692, __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, 1725, __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_4_Fst_27num_input_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1692, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20136,10 +20150,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_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, 1692, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1725, __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, 1692, __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, 1725, __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;
@@ -20158,7 +20172,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1707
+  /* "pywrapfst.pyx":1740
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -20167,11 +20181,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1707, __pyx_L1_error)
+    __PYX_ERR(0, 1740, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1708
+  /* "pywrapfst.pyx":1741
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20181,14 +20195,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1709
+    /* "pywrapfst.pyx":1742
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1709, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1742, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20202,14 +20216,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_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, 1709, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1742, __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, 1709, __pyx_L1_error)
+    __PYX_ERR(0, 1742, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1708
+    /* "pywrapfst.pyx":1741
  *     """
  *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20218,7 +20232,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1710
+  /* "pywrapfst.pyx":1743
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
@@ -20228,7 +20242,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1692
+  /* "pywrapfst.pyx":1725
  *     return result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20243,7 +20257,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -20251,38 +20265,38 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(struct __pyx_obj_9pywr
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1692, __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, 1725, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_input_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1692, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1692, __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, 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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20291,7 +20305,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_input_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -20299,7 +20313,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1712
+/* "pywrapfst.pyx":1745
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20307,8 +20321,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_26num_input_epsilons(struct __pyx_obj
  *     num_output_epsilons(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+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_r;
   __Pyx_RefNannyDeclarations
@@ -20329,10 +20343,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(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_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1712, __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, 1745, __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_4_Fst_29num_output_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1712, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20348,10 +20362,10 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(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, 1712, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1745, __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, 1712, __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, 1745, __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;
@@ -20370,7 +20384,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":1727
+  /* "pywrapfst.pyx":1760
  *       FstIndexError: State index out of range.
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
@@ -20379,11 +20393,11 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1727, __pyx_L1_error)
+    __PYX_ERR(0, 1760, __pyx_L1_error)
   }
   __pyx_v_result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1728
+  /* "pywrapfst.pyx":1761
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20393,14 +20407,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1729
+    /* "pywrapfst.pyx":1762
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     return result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1729, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1762, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20414,14 +20428,14 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
     }
     __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, 1729, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __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, 1729, __pyx_L1_error)
+    __PYX_ERR(0, 1762, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1728
+    /* "pywrapfst.pyx":1761
  *     """
  *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
  *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
@@ -20430,17 +20444,17 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":1730
+  /* "pywrapfst.pyx":1763
  *     if result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  *     return result             # <<<<<<<<<<<<<<
  * 
- *   cpdef _FstSymbolTable output_symbols(self):
+ *   cpdef _FstSymbolTableView output_symbols(self):
  */
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1712
+  /* "pywrapfst.pyx":1745
  *     return result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20455,7 +20469,7 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -20463,38 +20477,38 @@ static size_t __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(struct __pyx_obj_9pyw
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_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_4_Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1712, __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, 1745, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("num_output_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1712, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1712, __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, 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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20503,7 +20517,194 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(struct __pyx_ob
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.num_output_epsilons", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1765
+ *     return result
+ * 
+ *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     output_symbols(self)
+ */
+
+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;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  __Pyx_RefNannySetupContext("output_symbols", 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_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1765, __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));
+        __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, 1765, __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)
+        __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_2);
+        __pyx_t_2 = 0;
+        __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":1771
+ *     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:
+ *       return
+ */
+  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_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);
+  if (__pyx_t_5) {
+
+    /* "pywrapfst.pyx":1773
+ *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
+ *     if syms == NULL:
+ *       return             # <<<<<<<<<<<<<<
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
+ * 
+ */
+    __Pyx_XDECREF(((PyObject *)__pyx_r));
+    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
+    goto __pyx_L0;
+
+    /* "pywrapfst.pyx":1772
+ *     """
+ *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
+ *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *       return
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
+ */
+  }
+
+  /* "pywrapfst.pyx":1774
+ *     if syms == NULL:
+ *       return
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef string print(self, _SymbolTable 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_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_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
+ * 
+ *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     output_symbols(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_AddTraceback("pywrapfst.Fst.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF((PyObject *)__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_3Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_30output_symbols[] = "\n    output_symbols(self)\n\n    Returns the FST's output symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("output_symbols (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_30output_symbols(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __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_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.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -20511,25 +20712,85 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_28num_output_epsilons(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1732
- *     return result
+/* "pywrapfst.pyx":1776
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
+ * 
+ *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
+ *       _SymbolTable osymbols=None, _SymbolTable 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);
+
+  /* "pywrapfst.pyx":1777
+ * 
+ *   cpdef string print(self, _SymbolTable isymbols=None,
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *       bool acceptor=False, bool show_weight_one=False,
+ *       missing_sym=b"") 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);
+
+  /* "pywrapfst.pyx":1778
+ *   cpdef string print(self, _SymbolTable isymbols=None,
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *       bool acceptor=False, bool show_weight_one=False,             # <<<<<<<<<<<<<<
+ *       missing_sym=b"") 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);
+  fst::SymbolTable const *__pyx_v__isymbols;
+  fst::SymbolTable const *__pyx_v__osymbols;
+  fst::SymbolTable const *__pyx_v__ssymbols;
+  std::stringstream __pyx_v_sstrm;
+  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;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  std::string __pyx_t_9;
+  int __pyx_t_10;
+  int __pyx_t_11;
+  fst::SymbolTable const *__pyx_t_12;
+  __Pyx_RefNannySetupContext("print", 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":1776
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     """
- *     output_symbols(self)
+ *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *       bool acceptor=False, bool show_weight_one=False,
  */
-
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_output_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable *__pyx_v_syms;
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *__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_t_5;
-  __Pyx_RefNannySetupContext("output_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -20539,29 +20800,78 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     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, 1732, __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, 1776, __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_4_Fst_31output_symbols)) {
-        __Pyx_XDECREF(((PyObject *)__pyx_r));
+      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_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_GOTREF(__pyx_t_4);
         __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_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_INCREF(function);
-            __Pyx_DECREF_SET(__pyx_t_3, function);
+            __Pyx_DECREF_SET(__pyx_t_5, function);
+            __pyx_t_7 = 1;
           }
         }
-        __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, 1732, __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__FstSymbolTable))))) __PYX_ERR(0, 1732, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_2);
-        __pyx_t_2 = 0;
+        #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_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, 1776, __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, 1776, __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, 1776, __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+        __pyx_r = __pyx_t_9;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         goto __pyx_L0;
       }
@@ -20578,81 +20888,189 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
     #endif
   }
 
-  /* "pywrapfst.pyx":1739
+  /* "pywrapfst.pyx":1802
  *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().OutputSymbols())             # <<<<<<<<<<<<<<
- *     if syms == NULL:
- *       return
+ *     # Prints FST to stringstream, then returns resulting string.
+ *     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, 1739, __pyx_L1_error)
+    __PYX_ERR(0, 1802, __pyx_L1_error)
   }
+  __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1738
- *     Returns the FST's output symbol table, or None if none is present.
- *     """
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](             # <<<<<<<<<<<<<<
- *       self._fst.get().OutputSymbols())
- *     if syms == NULL:
+  /* "pywrapfst.pyx":1803
+ *     # Prints FST to stringstream, then returns resulting string.
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
-  __pyx_v_syms = const_cast<__pyx_t_9pywrapfst_SymbolTable_ptr>(__pyx_v_self->_fst.get()->OutputSymbols());
+  __pyx_t_10 = (((PyObject *)__pyx_v_isymbols) != Py_None);
+  __pyx_t_11 = (__pyx_t_10 != 0);
+  if (__pyx_t_11) {
 
-  /* "pywrapfst.pyx":1740
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_FstSymbolTable(syms, self._fst)
+    /* "pywrapfst.pyx":1804
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
  */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
-  if (__pyx_t_5) {
+    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_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_v__isymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1741
- *       self._fst.get().OutputSymbols())
- *     if syms == NULL:
- *       return             # <<<<<<<<<<<<<<
- *     return _init_FstSymbolTable(syms, self._fst)
- * 
+    /* "pywrapfst.pyx":1803
+ *     # Prints FST to stringstream, then returns resulting string.
+ *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+ *     if isymbols is not None:             # <<<<<<<<<<<<<<
+ *        _isymbols = isymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  */
-    __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)Py_None); __Pyx_INCREF(Py_None);
-    goto __pyx_L0;
+  }
 
-    /* "pywrapfst.pyx":1740
- *     cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
- *       self._fst.get().OutputSymbols())
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_FstSymbolTable(syms, self._fst)
+  /* "pywrapfst.pyx":1805
+ *     if isymbols is not None:
+ *        _isymbols = isymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._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, 1805, __pyx_L1_error)
   }
+  __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1742
- *     if syms == NULL:
- *       return
- *     return _init_FstSymbolTable(syms, self._fst)             # <<<<<<<<<<<<<<
- * 
- *   cpdef uint64 properties(self, uint64 mask, bool test):
+  /* "pywrapfst.pyx":1806
+ *        _isymbols = isymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
+ */
+  __pyx_t_11 = (((PyObject *)__pyx_v_osymbols) != Py_None);
+  __pyx_t_10 = (__pyx_t_11 != 0);
+  if (__pyx_t_10) {
+
+    /* "pywrapfst.pyx":1807
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
+ */
+    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_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_v__osymbols = __pyx_t_12;
+
+    /* "pywrapfst.pyx":1806
+ *        _isymbols = isymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+ *     if osymbols is not None:             # <<<<<<<<<<<<<<
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
+ */
+  }
+
+  /* "pywrapfst.pyx":1808
+ *     if osymbols is not None:
+ *        _osymbols = osymbols._raw_ptr_or_raise()
+ *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
+ */
+  __pyx_v__ssymbols = NULL;
+
+  /* "pywrapfst.pyx":1809
+ *        _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
+ */
+  __pyx_t_10 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_11 = (__pyx_t_10 != 0);
+  if (__pyx_t_11) {
+
+    /* "pywrapfst.pyx":1810
+ *     cdef const fst.SymbolTable *_ssymbols = NULL
+ *     if ssymbols is not None:
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     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_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_v__ssymbols = __pyx_t_12;
+
+    /* "pywrapfst.pyx":1809
+ *        _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
+ */
+  }
+
+  /* "pywrapfst.pyx":1812
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
+ *     cdef stringstream sstrm
+ *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
+ *               sstrm,
+ *               b"<pywrapfst>",
  */
-  __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, 1742, __pyx_L1_error)
+    __PYX_ERR(0, 1812, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTable(__pyx_v_syms, __pyx_v_self->_fst)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1742, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)__pyx_t_1);
-  __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":1820
+ *               acceptor,
+ *               show_weight_one,
+ *               tostring(missing_sym))             # <<<<<<<<<<<<<<
+ *     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)
+
+  /* "pywrapfst.pyx":1812
+ *       _ssymbols = ssymbols._raw_ptr_or_raise()
+ *     cdef stringstream sstrm
+ *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
+ *               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);
+
+  /* "pywrapfst.pyx":1821
+ *               show_weight_one,
+ *               tostring(missing_sym))
+ *     return sstrm.str()             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef uint64 properties(self, uint64 mask, bool test):
+ */
+  __pyx_r = __pyx_v_sstrm.str();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1732
- *     return result
+  /* "pywrapfst.pyx":1776
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef _FstSymbolTable output_symbols(self):             # <<<<<<<<<<<<<<
- *     """
- *     output_symbols(self)
+ *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *       bool acceptor=False, bool show_weight_one=False,
  */
 
   /* function exit code */
@@ -20661,44 +21079,201 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTable *__pyx_f_9pywrapfst_4_Fst_out
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._Fst.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("pywrapfst.Fst.print", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
-  __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_30output_symbols[] = "\n    output_symbols(self)\n\n    Returns the FST's output symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+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;
+  bool __pyx_v_acceptor;
+  bool __pyx_v_show_weight_one;
+  PyObject *__pyx_v_missing_sym = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("output_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_30output_symbols(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __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);
+
+    /* "pywrapfst.pyx":1777
+ * 
+ *   cpdef string print(self, _SymbolTable isymbols=None,
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *       bool acceptor=False, bool show_weight_one=False,
+ *       missing_sym=b"") 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);
+    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, "print") < 0)) __PYX_ERR(0, 1776, __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, 1778, __pyx_L3_error)
+    } else {
+
+      /* "pywrapfst.pyx":1778
+ *   cpdef string print(self, _SymbolTable isymbols=None,
+ *       _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, 1778, __pyx_L3_error)
+    } else {
+      __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("print", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1776, __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)
+  __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
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
+ * 
+ *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
+ *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *       bool acceptor=False, bool show_weight_one=False,
+ */
 
   /* function exit code */
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __pyx_r = NULL;
+  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_30output_symbols(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("output_symbols", 0);
+  std::string __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_3Fst_print __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  __Pyx_RefNannySetupContext("print", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1732, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __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->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_GOTREF(__pyx_t_3);
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pywrapfst.Fst.print", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -20706,17 +21281,17 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_30output_symbols(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1744
- *     return _init_FstSymbolTable(syms, self._fst)
+/* "pywrapfst.pyx":1823
+ *     return sstrm.str()
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
  *     properties(self, mask, test)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, bool __pyx_v_test, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint64 __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+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) {
+  uint64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -20726,7 +21301,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
   PyObject *__pyx_t_6 = NULL;
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
-  __pyx_t_10basictypes_uint64 __pyx_t_9;
+  uint64 __pyx_t_9;
   __Pyx_RefNannySetupContext("properties", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -20737,12 +21312,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(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_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1744, __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, 1823, __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_4_Fst_33properties)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1744, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1744, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1823, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -20760,7 +21335,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
         #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, 1744, __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, 1823, __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;
@@ -20770,7 +21345,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
         #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, 1744, __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, 1823, __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;
@@ -20778,7 +21353,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1744, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1823, __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;
@@ -20789,12 +21364,12 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
           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, 1744, __pyx_L1_error)
+          __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_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1744, __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, 1823, __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;
@@ -20813,22 +21388,22 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
     #endif
   }
 
-  /* "pywrapfst.pyx":1762
+  /* "pywrapfst.pyx":1841
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._fst.get().Properties(mask, test)             # <<<<<<<<<<<<<<
  * 
- *   cpdef int64 start(self):
+ *   @classmethod
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1762, __pyx_L1_error)
+    __PYX_ERR(0, 1841, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Properties(__pyx_v_mask, __pyx_v_test);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1744
- *     return _init_FstSymbolTable(syms, self._fst)
+  /* "pywrapfst.pyx":1823
+ *     return sstrm.str()
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
@@ -20844,7 +21419,7 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -20852,10 +21427,10 @@ static __pyx_t_10basictypes_uint64 __pyx_f_9pywrapfst_4_Fst_properties(struct __
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_32properties[] = "\n    properties(self, mask, test)\n\n    Provides property bits.\n\n    This method provides user access to the properties attributes for the FST.\n    The resulting value is a long integer, but when it is cast to a boolean,\n    it represents whether or not the FST has the `mask` property.\n\n    Args:\n      mask: The property mask to be compared to the FST's properties.\n      test: Should any unknown values be computed before comparing against\n          the mask?\n\n    Returns:\n      A 64-bit bitmask representing the requested properties.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint64 __pyx_v_mask;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_34properties[] = "\n    properties(self, mask, test)\n\n    Provides property bits.\n\n    This method provides user access to the properties attributes for the FST.\n    The resulting value is a long integer, but when it is cast to a boolean,\n    it represents whether or not the FST has the `mask` property.\n\n    Args:\n      mask: The property mask to be compared to the FST's properties.\n      test: Should any unknown values be computed before comparing against\n          the mask?\n\n    Returns:\n      A 64-bit bitmask representing the requested properties.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -20883,11 +21458,11 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self,
         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, 1744, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1823, __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, 1744, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1823, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -20895,31 +21470,31 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_33properties(PyObject *__pyx_v_self,
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1744, __pyx_L3_error)
-    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1744, __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, 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)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1744, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1823, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_32properties(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), __pyx_v_mask, __pyx_v_test);
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_34properties(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_mask, __pyx_v_test);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_mask, bool __pyx_v_test) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, uint64 __pyx_v_mask, bool __pyx_v_test) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("properties", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_4_Fst_properties(__pyx_v_self, __pyx_v_mask, __pyx_v_test, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1744, __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, 1823, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20928,7 +21503,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(struct __pyx_obj_9pywrap
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -20936,23 +21511,145 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_32properties(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1764
- *     return self._fst.get().Properties(mask, test)
+/* "pywrapfst.pyx":1844
+ * 
+ *   @classmethod
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
+ *     """
+ *     read(source)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_3Fst_37read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_36read[] = "\n    read(source)\n\n    Reads an FST from a file.\n\n    Args:\n      source: The string location of the input file.\n\n    Returns:\n      An FST object.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_37read(PyObject *__pyx_v_cls, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_36read(((PyTypeObject*)__pyx_v_cls), ((PyObject *)__pyx_v_source));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  __Pyx_RefNannySetupContext("read", 0);
+
+  /* "pywrapfst.pyx":1859
+ *       FstIOError: Read failed.
+ *     """
+ *     return _read_Fst(source)             # <<<<<<<<<<<<<<
+ * 
+ *   @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_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1844
+ * 
+ *   @classmethod
+ *   def read(cls, source):             # <<<<<<<<<<<<<<
+ *     """
+ *     read(source)
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst.Fst.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1862
+ * 
+ *   @classmethod
+ *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_3Fst_39read_from_string(PyObject *__pyx_v_cls, PyObject *__pyx_v_state); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_38read_from_string[] = "\n    read_from_string(state)\n\n    Reads an FST from a serialized string.\n\n    Args:\n      state: A string containing the serialized FST.\n\n    Returns:\n      An FST object.\n\n    Raises:\n      FstIOError: Read failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_39read_from_string(PyObject *__pyx_v_cls, PyObject *__pyx_v_state) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("read_from_string (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_38read_from_string(((PyTypeObject*)__pyx_v_cls), ((PyObject *)__pyx_v_state));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+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;
+  __Pyx_RefNannySetupContext("read_from_string", 0);
+
+  /* "pywrapfst.pyx":1877
+ *       FstIOError: Read failed.
+ *     """
+ *     return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
+ * 
+ *   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;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":1862
+ * 
+ *   @classmethod
+ *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
+ *     """
+ *     read_from_string(state)
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst.Fst.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":1879
+ *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
  *     """
  *     start(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_35start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_41start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
+  int64 __pyx_t_5;
   __Pyx_RefNannySetupContext("start", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -20963,9 +21660,9 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(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_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1764, __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, 1879, __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_4_Fst_35start)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_41start)) {
         __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))) {
@@ -20979,10 +21676,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(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, 1764, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1879, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1764, __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, 1879, __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;
@@ -21001,7 +21698,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1770
+  /* "pywrapfst.pyx":1885
  *     Returns the start state.
  *     """
  *     return self._fst.get().Start()             # <<<<<<<<<<<<<<
@@ -21010,13 +21707,13 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1770, __pyx_L1_error)
+    __PYX_ERR(0, 1885, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Start();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1764
- *     return self._fst.get().Properties(mask, test)
+  /* "pywrapfst.pyx":1879
+ *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
  *     """
@@ -21029,7 +21726,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.start", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.start", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -21037,26 +21734,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_4_Fst_start(struct __pyx_ob
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_35start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_34start[] = "\n    start(self)\n\n    Returns the start state.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_35start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_41start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_40start[] = "\n    start(self)\n\n    Returns the start state.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_41start(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("start (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_34start(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_40start(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("start", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_4_Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1764, __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, 1879, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21065,7 +21762,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -21073,7 +21770,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1772
+/* "pywrapfst.pyx":1887
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -21081,8 +21778,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_34start(struct __pyx_obj_9pywrapfst__
  *     states(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_37states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_states(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst_StateIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -21099,9 +21796,9 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
     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, 1772, __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, 1887, __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_4_Fst_37states)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_43states)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -21116,10 +21813,10 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
         }
         __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, 1772, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1887, __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, 1772, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1887, __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;
@@ -21138,21 +21835,21 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
     #endif
   }
 
-  /* "pywrapfst.pyx":1781
+  /* "pywrapfst.pyx":1896
  *       A StateIterator object for the FST.
  *     """
  *     return StateIterator(self)             # <<<<<<<<<<<<<<
  * 
- *   cpdef string text(self, _SymbolTable isymbols=None,
+ *   # TODO(kbg): Deprecated; remove on next release.
  */
   __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, 1781, __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, 1896, __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":1772
+  /* "pywrapfst.pyx":1887
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -21166,7 +21863,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._Fst.states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -21175,26 +21872,26 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_4_Fst_state
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_37states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_36states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A StateIterator object for the FST.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_37states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_42states[] = "\n    states(self)\n\n    Returns an iterator over all states in the FST.\n\n    Returns:\n      A StateIterator object for the FST.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_43states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("states (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_36states(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_42states(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_4_Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1772, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21203,7 +21900,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -21211,42 +21908,62 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_36states(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1783
- *     return StateIterator(self)
+/* "pywrapfst.pyx":1899
  * 
- *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
+ *   # TODO(kbg): Deprecated; remove on next release.
+ *   cpdef string text(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=None,
+ *                     _SymbolTable osymbols=None,
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_text *__pyx_optional_args) {
+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":1784
- * 
- *   cpdef string text(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
- *     """
+  /* "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":1785
- *   cpdef string text(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
- *     """
- *     text(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,
+  /* "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 *:
+ *     """
+ */
   bool __pyx_v_show_weight_one = ((bool)0);
   PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b__8);
-  fst::SymbolTable const *__pyx_v__isymbols;
-  fst::SymbolTable const *__pyx_v__osymbols;
-  fst::SymbolTable *__pyx_v__ssymbols;
-  std::stringstream __pyx_v_sstrm;
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -21258,9 +21975,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
   std::string __pyx_t_9;
-  int __pyx_t_10;
-  int __pyx_t_11;
-  fst::SymbolTable *__pyx_t_12;
+  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) {
@@ -21283,12 +21998,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     }
   }
 
-  /* "pywrapfst.pyx":1783
- *     return StateIterator(self)
+  /* "pywrapfst.pyx":1899
  * 
- *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
+ *   # TODO(kbg): Deprecated; remove on next release.
+ *   cpdef string text(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=None,
+ *                     _SymbolTable osymbols=None,
  */
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -21299,12 +22014,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     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, 1783, __pyx_L1_error)
+      __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_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_4_Fst_39text)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+      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, 1783, __pyx_L1_error)
+        __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);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -21322,7 +22037,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
         #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, 1783, __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, 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;
@@ -21332,7 +22047,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
         #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, 1783, __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, 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;
@@ -21340,7 +22055,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1783, __pyx_L1_error)
+          __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;
@@ -21363,12 +22078,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
           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, 1783, __pyx_L1_error)
+          __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, 1783, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_9;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21387,223 +22102,63 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
     #endif
   }
 
-  /* "pywrapfst.pyx":1808
+  /* "pywrapfst.pyx":1927
+ *       A formatted string representing the machine.
  *     """
- *     # Prints FST to stringstream, then returns resulting string.
- *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
- *     if isymbols is not None:
- *        _isymbols = isymbols._table
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1808, __pyx_L1_error)
-  }
-  __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
-
-  /* "pywrapfst.pyx":1809
- *     # Prints FST to stringstream, then returns resulting string.
- *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
- *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *        _isymbols = isymbols._table
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- */
-  __pyx_t_10 = (((PyObject *)__pyx_v_isymbols) != Py_None);
-  __pyx_t_11 = (__pyx_t_10 != 0);
-  if (__pyx_t_11) {
-
-    /* "pywrapfst.pyx":1810
- *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
- *     if isymbols is not None:
- *        _isymbols = isymbols._table             # <<<<<<<<<<<<<<
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- *     if osymbols is not None:
+ *     warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)             # <<<<<<<<<<<<<<
+ *     return self.print(isymbols,
+ *                       osymbols,
  */
-    if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1810, __pyx_L1_error)
-    }
-    __pyx_t_12 = __pyx_v_isymbols->_table;
-    __pyx_v__isymbols = __pyx_t_12;
-
-    /* "pywrapfst.pyx":1809
- *     # Prints FST to stringstream, then returns resulting string.
- *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
- *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *        _isymbols = isymbols._table
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- */
-  }
-
-  /* "pywrapfst.pyx":1811
- *     if isymbols is not None:
- *        _isymbols = isymbols._table
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
- *     if osymbols is not None:
- *        _osymbols = osymbols._table
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1811, __pyx_L1_error)
-  }
-  __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
-
-  /* "pywrapfst.pyx":1812
- *        _isymbols = isymbols._table
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
- */
-  __pyx_t_11 = (((PyObject *)__pyx_v_osymbols) != Py_None);
-  __pyx_t_10 = (__pyx_t_11 != 0);
-  if (__pyx_t_10) {
-
-    /* "pywrapfst.pyx":1813
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- *     if osymbols is not None:
- *        _osymbols = osymbols._table             # <<<<<<<<<<<<<<
- *     cdef fst.SymbolTable *_ssymbols = NULL
- *     if ssymbols is not None:
- */
-    if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1813, __pyx_L1_error)
-    }
-    __pyx_t_12 = __pyx_v_osymbols->_table;
-    __pyx_v__osymbols = __pyx_t_12;
-
-    /* "pywrapfst.pyx":1812
- *        _isymbols = isymbols._table
- *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
- *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
- */
-  }
-
-  /* "pywrapfst.pyx":1814
- *     if osymbols is not None:
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
- */
-  __pyx_v__ssymbols = NULL;
-
-  /* "pywrapfst.pyx":1815
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
- *     if ssymbols is not None:
- */
-  __pyx_t_10 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
-  __pyx_t_11 = (__pyx_t_10 != 0);
-  if (__pyx_t_11) {
-
-    /* "pywrapfst.pyx":1816
- *     cdef fst.SymbolTable *_ssymbols = NULL
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
- */
-    if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 1816, __pyx_L1_error)
-    }
-    __pyx_t_12 = __pyx_v_ssymbols->_table;
-    __pyx_v__ssymbols = __pyx_t_12;
-
-    /* "pywrapfst.pyx":1815
- *        _osymbols = osymbols._table
- *     cdef fst.SymbolTable *_ssymbols = NULL
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
- *     if ssymbols is not None:
- */
-  }
-
-  /* "pywrapfst.pyx":1817
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
- *     cdef stringstream sstrm
- */
-  __pyx_t_11 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
-  __pyx_t_10 = (__pyx_t_11 != 0);
-  if (__pyx_t_10) {
-
-    /* "pywrapfst.pyx":1818
- *       _ssymbols = ssymbols._table
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
- *     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'", "_table");
-      __PYX_ERR(0, 1818, __pyx_L1_error)
-    }
-    __pyx_t_12 = __pyx_v_ssymbols->_table;
-    __pyx_v__ssymbols = __pyx_t_12;
-
-    /* "pywrapfst.pyx":1817
- *     if ssymbols is not None:
- *       _ssymbols = ssymbols._table
- *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       _ssymbols = ssymbols._table
- *     cdef stringstream sstrm
- */
-  }
+  __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":1820
- *       _ssymbols = ssymbols._table
- *     cdef stringstream sstrm
- *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
- *               sstrm,
- *               b"<pywrapfst>",
+  /* "pywrapfst.pyx":1928
+ *     """
+ *     warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)
+ *     return self.print(isymbols,             # <<<<<<<<<<<<<<
+ *                       osymbols,
+ *                       ssymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1820, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "print");
+    __PYX_ERR(0, 1928, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1828
- *               acceptor,
- *               show_weight_one,
- *               tostring(missing_sym))             # <<<<<<<<<<<<<<
- *     return sstrm.str()
+  /* "pywrapfst.pyx":1933
+ *                       acceptor,
+ *                       show_weight_one,
+ *                       missing_sym)             # <<<<<<<<<<<<<<
  * 
- */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1828, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":1820
- *       _ssymbols = ssymbols._table
- *     cdef stringstream sstrm
- *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
- *               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);
-
-  /* "pywrapfst.pyx":1829
- *               show_weight_one,
- *               tostring(missing_sym))
- *     return sstrm.str()             # <<<<<<<<<<<<<<
  * 
- *   cpdef bool verify(self):
  */
-  __pyx_r = __pyx_v_sstrm.str();
+  __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1783
- *     return StateIterator(self)
+  /* "pywrapfst.pyx":1899
  * 
- *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
+ *   # TODO(kbg): Deprecated; remove on next release.
+ *   cpdef string text(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=None,
+ *                     _SymbolTable osymbols=None,
  */
 
   /* function exit code */
@@ -21615,7 +22170,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_AddTraceback("pywrapfst.Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -21623,9 +22178,9 @@ static std::string __pyx_f_9pywrapfst_4_Fst_text(struct __pyx_obj_9pywrapfst__Fs
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_38text[] = "\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_4_Fst_39text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+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;
@@ -21638,16 +22193,32 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObje
   {
     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":1784
- * 
- *   cpdef string text(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
- *     """
+    /* "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)) {
@@ -21708,7 +22279,7 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "text") < 0)) __PYX_ERR(0, 1783, __pyx_L3_error)
+        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)) {
@@ -21732,44 +22303,52 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObje
     __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, 1785, __pyx_L3_error)
+      __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":1785
- *   cpdef string text(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):             # <<<<<<<<<<<<<<
- *     """
- *     text(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,
+      /* "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, 1785, __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, 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, 1783, __pyx_L3_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_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, 1783, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1784, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1784, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_38text(((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);
+  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":1783
- *     return StateIterator(self)
+  /* "pywrapfst.pyx":1899
  * 
- *   cpdef string text(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
- *       bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
+ *   # TODO(kbg): Deprecated; remove on next release.
+ *   cpdef string text(self,             # <<<<<<<<<<<<<<
+ *                     _SymbolTable isymbols=None,
+ *                     _SymbolTable osymbols=None,
  */
 
   /* function exit code */
@@ -21781,11 +22360,11 @@ static PyObject *__pyx_pw_9pywrapfst_4_Fst_39text(PyObject *__pyx_v_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(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_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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
-  struct __pyx_opt_args_9pywrapfst_4_Fst_text __pyx_t_2;
+  struct __pyx_opt_args_9pywrapfst_3Fst_text __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("text", 0);
   __Pyx_XDECREF(__pyx_r);
@@ -21796,8 +22375,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(struct __pyx_obj_9pywrapfst__F
   __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); 
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1783, __pyx_L1_error)
+  __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;
@@ -21806,7 +22385,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(struct __pyx_obj_9pywrapfst__F
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -21814,16 +22393,16 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_38text(struct __pyx_obj_9pywrapfst__F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1831
- *     return sstrm.str()
+/* "pywrapfst.pyx":1936
+ * 
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
  *     """
  *     verify(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_41verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+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;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -21841,9 +22420,9 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(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_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1831, __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, 1936, __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_4_Fst_41verify)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_47verify)) {
         __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))) {
@@ -21857,10 +22436,10 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
         }
         __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, 1831, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1936, __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, 1831, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21879,7 +22458,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
     #endif
   }
 
-  /* "pywrapfst.pyx":1840
+  /* "pywrapfst.pyx":1945
  *       True if the contents are sane, False otherwise.
  *     """
  *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
@@ -21888,13 +22467,13 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(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, 1840, __pyx_L1_error)
+    __PYX_ERR(0, 1945, __pyx_L1_error)
   }
   __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1831
- *     return sstrm.str()
+  /* "pywrapfst.pyx":1936
+ * 
  * 
  *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
  *     """
@@ -21907,7 +22486,7 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
   __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_WriteUnraisable("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -21915,26 +22494,26 @@ static bool __pyx_f_9pywrapfst_4_Fst_verify(struct __pyx_obj_9pywrapfst__Fst *__
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_41verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_40verify[] = "\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_4_Fst_41verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+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_4_Fst_40verify(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __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_4_Fst_40verify(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+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_4_Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1831, __pyx_L1_error)
+  __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;
@@ -21943,7 +22522,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(struct __pyx_obj_9pywrapfst_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -21951,7 +22530,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1842
+/* "pywrapfst.pyx":1947
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -21959,8 +22538,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_40verify(struct __pyx_obj_9pywrapfst_
  *     weight_type(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_43weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+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;
@@ -21978,9 +22557,9 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(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_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1842, __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, 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_4_Fst_43weight_type)) {
+      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))) {
@@ -21994,10 +22573,10 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(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, 1842, __pyx_L1_error)
+        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, 1842, __pyx_L1_error)
+        __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;
@@ -22016,7 +22595,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1851
+  /* "pywrapfst.pyx":1956
  *       A string representing the weight type.
  *     """
  *     return self._fst.get().WeightType()             # <<<<<<<<<<<<<<
@@ -22025,12 +22604,12 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1851, __pyx_L1_error)
+    __PYX_ERR(0, 1956, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1842
+  /* "pywrapfst.pyx":1947
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -22044,7 +22623,7 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._Fst.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -22052,26 +22631,26 @@ static std::string __pyx_f_9pywrapfst_4_Fst_weight_type(struct __pyx_obj_9pywrap
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_43weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_42weight_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_4_Fst_43weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("weight_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_42weight_type(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_48weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_48weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_4_Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1842, __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, 1947, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22080,7 +22659,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywra
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.weight_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22088,7 +22667,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1853
+/* "pywrapfst.pyx":1958
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22096,8 +22675,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_42weight_type(struct __pyx_obj_9pywra
  *     write(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_51write(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;
   PyObject *__pyx_t_2 = NULL;
@@ -22116,9 +22695,9 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     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, 1853, __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, 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_4_Fst_45write)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_51write)) {
         __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))) {
@@ -22132,7 +22711,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
         }
         __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, 1853, __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;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -22152,7 +22731,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     #endif
   }
 
-  /* "pywrapfst.pyx":1867
+  /* "pywrapfst.pyx":1972
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
@@ -22161,22 +22740,22 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1867, __pyx_L1_error)
+    __PYX_ERR(0, 1972, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1867, __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_6 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1868
+    /* "pywrapfst.pyx":1973
  *     """
  *     if not self._fst.get().Write(tostring(source)):
  *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1868, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1973, __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, 1868, __pyx_L1_error)
+    __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))) {
@@ -22190,7 +22769,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     }
     __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, 1868, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1973, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = NULL;
@@ -22206,14 +22785,14 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
     __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, 1868, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1973, __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, 1868, __pyx_L1_error)
+    __PYX_ERR(0, 1973, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1867
+    /* "pywrapfst.pyx":1972
  *       FstIOError: Write failed.
  *     """
  *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
@@ -22222,7 +22801,7 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
  */
   }
 
-  /* "pywrapfst.pyx":1853
+  /* "pywrapfst.pyx":1958
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22238,33 +22817,33 @@ static void __pyx_f_9pywrapfst_4_Fst_write(struct __pyx_obj_9pywrapfst__Fst *__p
   __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_AddTraceback("pywrapfst.Fst.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_44write[] = "\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_4_Fst_45write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
+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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_44write(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_50write(((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_4_Fst_44write(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_50write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_4_Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1853, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1853, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22273,7 +22852,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22281,7 +22860,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1870
+/* "pywrapfst.pyx":1975
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -22289,8 +22868,8 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_44write(struct __pyx_obj_9pywrapfst__
  *     write_to_string(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_47write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_53write_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;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -22309,9 +22888,9 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(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_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1870, __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, 1975, __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_4_Fst_47write_to_string)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_53write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -22326,10 +22905,10 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(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, 1870, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1975, __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, 1870, __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, 1975, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22348,7 +22927,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1883
+  /* "pywrapfst.pyx":1988
  *     """
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -22357,19 +22936,19 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1883, __pyx_L1_error)
+    __PYX_ERR(0, 1988, __pyx_L1_error)
   }
   __pyx_t_5 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1884
+    /* "pywrapfst.pyx":1989
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
  *     return sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1884, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1989, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -22383,14 +22962,14 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
     }
     __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, 1884, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1989, __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, 1884, __pyx_L1_error)
+    __PYX_ERR(0, 1989, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1883
+    /* "pywrapfst.pyx":1988
  *     """
  *     cdef stringstream sstrm
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
@@ -22399,7 +22978,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":1885
+  /* "pywrapfst.pyx":1990
  *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")
  *     return sstrm.str()             # <<<<<<<<<<<<<<
@@ -22407,13 +22986,13 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
  * 
  */
   __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, 1885, __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, 1990, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1870
+  /* "pywrapfst.pyx":1975
  *       raise FstIOError("Write failed: {!r}".format(source))
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
@@ -22427,7 +23006,7 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22436,26 +23015,26 @@ static PyObject *__pyx_f_9pywrapfst_4_Fst_write_to_string(struct __pyx_obj_9pywr
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_4_Fst_47write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_4_Fst_46write_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_4_Fst_47write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+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) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write_to_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_4_Fst_46write_to_string(((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_52write_to_string(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_52write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_4_Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1870, __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, 1975, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22464,7 +23043,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.Fst.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22472,7 +23051,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1898
+/* "pywrapfst.pyx":2003
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -22480,7 +23059,7 @@ static PyObject *__pyx_pf_9pywrapfst_4_Fst_46write_to_string(struct __pyx_obj_9p
  * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -22488,28 +23067,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_check_mutating_imethod", 0);
 
-  /* "pywrapfst.pyx":1903
+  /* "pywrapfst.pyx":2008
  *     This function is not visible to Python users.
  *     """
  *     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 (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1903, __pyx_L1_error)
+    __PYX_ERR(0, 2008, __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":1904
+    /* "pywrapfst.pyx":2009
  *     """
  *     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, 1904, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2009, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22523,23 +23102,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
     }
     __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, 1904, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2009, __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, 1904, __pyx_L1_error)
+    __PYX_ERR(0, 2009, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1903
+    /* "pywrapfst.pyx":2008
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Operation failed")
- * 
+ *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  */
   }
 
-  /* "pywrapfst.pyx":1898
+  /* "pywrapfst.pyx":2003
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -22553,20 +23132,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod(struct __py
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._check_mutating_imethod", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._check_mutating_imethod", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1906
+/* "pywrapfst.pyx":2010
+ *     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):
  *       raise FstIndexError("State index out of range")
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
+static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -22574,8 +23153,8 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_add_arc", 0);
 
-  /* "pywrapfst.pyx":1907
- * 
+  /* "pywrapfst.pyx":2011
+ *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
@@ -22583,19 +23162,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1907, __pyx_L1_error)
+    __PYX_ERR(0, 2011, __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":1908
+    /* "pywrapfst.pyx":2012
  *   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, 1908, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2012, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22609,15 +23188,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
     }
     __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, 1908, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2012, __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, 1908, __pyx_L1_error)
+    __PYX_ERR(0, 2012, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1907
- * 
+    /* "pywrapfst.pyx":2011
+ *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
@@ -22625,32 +23204,32 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1909
+  /* "pywrapfst.pyx":2013
  *     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")
- *     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, 1909, __pyx_L1_error)
+    __PYX_ERR(0, 2013, __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, 1909, __pyx_L1_error)
+    __PYX_ERR(0, 2013, __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":1910
+    /* "pywrapfst.pyx":2014
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   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, 1910, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2014, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22664,38 +23243,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
     }
     __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, 1910, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2014, __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, 1910, __pyx_L1_error)
+    __PYX_ERR(0, 2014, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1909
+    /* "pywrapfst.pyx":2013
  *     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")
- *     self._check_mutating_imethod()
- */
-  }
-
-  /* "pywrapfst.pyx":1911
- *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
- *       raise FstOpError("Incompatible or invalid weight type")
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def add_arc(self, int64 state, Arc arc):
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1911, __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, 1911, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1906
+  /* "pywrapfst.pyx":2010
+ *     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):
  *       raise FstIndexError("State index out of range")
@@ -22707,13 +23273,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1913
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2016
+ *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
  *     """
@@ -22721,10 +23287,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__add_arc(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_add_arc[] = "\n    add_arc(self, state, arc)\n\n    Adds a new arc to the FST and return self.\n\n    Args:\n      state: The integer index of the source state.\n      arc: The arc to add.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpdexError: Incompatible or invalid weight type.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_add_arc[] = "\n    add_arc(self, state, arc)\n\n    Adds a new arc to the FST and return self.\n\n    Args:\n      state: The integer index of the source state.\n      arc: The arc to add.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpdexError: Incompatible or invalid weight type.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -22752,11 +23318,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
         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, 1913, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 2016, __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, 1913, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 2016, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -22764,19 +23330,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1913, __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, 2016, __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, 1913, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2016, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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, 1913, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_add_arc(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_arc);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 2016, __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 */
   goto __pyx_L0;
@@ -22787,12 +23353,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_1add_arc(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
+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
   __Pyx_RefNannySetupContext("add_arc", 0);
 
-  /* "pywrapfst.pyx":1930
+  /* "pywrapfst.pyx":2033
  *       FstOpdexError: Incompatible or invalid weight type.
  *     """
  *     self._add_arc(state, arc)             # <<<<<<<<<<<<<<
@@ -22801,24 +23367,24 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_add_arc");
-    __PYX_ERR(0, 1930, __pyx_L1_error)
+    __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, 1930, __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)
 
-  /* "pywrapfst.pyx":1931
+  /* "pywrapfst.pyx":2034
  *     """
  *     self._add_arc(state, arc)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cpdef int64 add_state(self) except *:
+ *   cpdef int64 add_state(self):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1913
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2016
+ *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
  *     """
@@ -22827,7 +23393,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22835,24 +23401,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_add_arc(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1933
+/* "pywrapfst.pyx":2036
  *     return self
  * 
- *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
+ *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
  *     """
  *     add_state(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_v_result;
-  __pyx_t_10basictypes_int64 __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int __pyx_skip_dispatch) {
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
+  int64 __pyx_t_5;
   __Pyx_RefNannySetupContext("add_state", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -22863,9 +23428,9 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(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_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1933, __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, 2036, __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_11_MutableFst_3add_state)) {
+      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);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22879,10 +23444,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(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, 1933, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2036, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1933, __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, 2036, __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;
@@ -22901,46 +23466,24 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
     #endif
   }
 
-  /* "pywrapfst.pyx":1942
+  /* "pywrapfst.pyx":2045
  *       The integer index of the new state.
  *     """
- *     cdef int64 result = self._mfst.get().AddState()             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
- *     return result
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1942, __pyx_L1_error)
-  }
-  __pyx_v_result = __pyx_v_self->_mfst.get()->AddState();
-
-  /* "pywrapfst.pyx":1943
- *     """
- *     cdef int64 result = self._mfst.get().AddState()
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- *     return result
+ *     return self._mfst.get().AddState()             # <<<<<<<<<<<<<<
  * 
+ *   cpdef void add_states(self, size_t n):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1943, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
+    __PYX_ERR(0, 2045, __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, 1943, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":1944
- *     cdef int64 result = self._mfst.get().AddState()
- *     self._check_mutating_imethod()
- *     return result             # <<<<<<<<<<<<<<
- * 
- *   cpdef void add_states(self, size_t n) except *:
- */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v_self->_mfst.get()->AddState();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1933
+  /* "pywrapfst.pyx":2036
  *     return self
  * 
- *   cpdef int64 add_state(self) except *:             # <<<<<<<<<<<<<<
+ *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
  *     """
  *     add_state(self)
  */
@@ -22951,7 +23494,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_state", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst.add_state", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -22959,37 +23502,35 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_add_state(str
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_2add_state[] = "\n    add_state(self)\n\n    Adds a new state to the FST and returns the state ID.\n\n    Returns:\n      The integer index of the new state.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_2add_state[] = "\n    add_state(self)\n\n    Adds a new state to the FST and returns the state ID.\n\n    Returns:\n      The integer index of the new state.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_3add_state(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_state (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_2add_state(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_2add_state(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __pyx_t_10basictypes_int64 __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("add_state", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_11_MutableFst_add_state(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1933, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1933, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_r = __pyx_t_2;
-  __pyx_t_2 = 0;
+  __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_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_2);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_state", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.add_state", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22997,16 +23538,16 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_2add_state(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1946
- *     return result
+/* "pywrapfst.pyx":2047
+ *     return self._mfst.get().AddState()
  * 
- *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
  *     """
  *     add_states(self, n)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
-static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, size_t __pyx_v_n, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -23023,10 +23564,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_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_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1946, __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, 2047, __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_11_MutableFst_5add_states)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1946, __pyx_L1_error)
+      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_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -23042,7 +23583,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
         __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, 1946, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2047, __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;
@@ -23062,36 +23603,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1955
+  /* "pywrapfst.pyx":2056
  *       n: The number of states to add.
  *     """
  *     self._mfst.get().AddStates(n)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1955, __pyx_L1_error)
+    __PYX_ERR(0, 2056, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->AddStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":1956
- *     """
- *     self._mfst.get().AddStates(n)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1956, __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, 1956, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":1946
- *     return result
+  /* "pywrapfst.pyx":2047
+ *     return self._mfst.get().AddState()
  * 
- *   cpdef void add_states(self, size_t n) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
  *     """
  *     add_states(self, n)
  */
@@ -23104,43 +23632,42 @@ static void __pyx_f_9pywrapfst_11_MutableFst_add_states(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+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;
   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, 1946, __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, 2047, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_4add_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((size_t)__pyx_v_n));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_4add_states(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((size_t)__pyx_v_n));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, size_t __pyx_v_n) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, size_t __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("add_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_11_MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1946, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1946, __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, 2047, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23149,7 +23676,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.add_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23157,15 +23684,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_4add_states(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1958
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2058
+ *     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)):
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args) {
+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;
   __Pyx_RefNannyDeclarations
@@ -23183,27 +23710,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1960
+  /* "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)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1960, __pyx_L1_error)
+  __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);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1961
+    /* "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)
- *     self._check_mutating_imethod()
+ * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1961, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2061, __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, 1961, __pyx_L1_error)
+    __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))) {
@@ -23217,7 +23744,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     }
     __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, 1961, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2061, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -23233,14 +23760,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
     __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, 1961, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2061, __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, 1961, __pyx_L1_error)
+    __PYX_ERR(0, 2061, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1960
+    /* "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)):             # <<<<<<<<<<<<<<
@@ -23249,34 +23776,21 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
   }
 
-  /* "pywrapfst.pyx":1962
+  /* "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)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def arcsort(self, sort_type=b"ilabel"):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1962, __pyx_L1_error)
+    __PYX_ERR(0, 2062, __pyx_L1_error)
   }
   fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v_sort_type_enum);
 
-  /* "pywrapfst.pyx":1963
- *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def arcsort(self, sort_type=b"ilabel"):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 1963, __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, 1963, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":1958
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2058
+ *     self._mfst.get().AddStates(n)
  * 
  *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
  *     cdef fst.ArcSortType sort_type_enum
@@ -23291,13 +23805,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
   __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_AddTraceback("pywrapfst.MutableFst._arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1965
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2064
+ *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
  *     """
@@ -23305,9 +23819,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__arcsort(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -23334,7 +23848,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(PyObject *__pyx_v_se
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 1965, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 2064, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23348,26 +23862,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_7arcsort(PyObject *__pyx_v_se
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1965, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2064, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_6arcsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_sort_type);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_6arcsort(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_sort_type);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_sort_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort __pyx_t_1;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":1984
+  /* "pywrapfst.pyx":2083
  *       FstArgError: Unknown sort type.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -23376,26 +23890,26 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arcsort");
-    __PYX_ERR(0, 1984, __pyx_L1_error)
+    __PYX_ERR(0, 2083, __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, 1984, __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, 2083, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1985
+  /* "pywrapfst.pyx":2084
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _closure(self, bool closure_plus=False) except *:
+ *   cdef void _closure(self, bool closure_plus=False):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1965
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2064
+ *     fst.ArcSort(self._mfst.get(), sort_type_enum)
  * 
  *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
  *     """
@@ -23404,7 +23918,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23412,15 +23926,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_6arcsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1987
+/* "pywrapfst.pyx":2086
  *     return self
  * 
- *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
- *     self._check_mutating_imethod()
+ * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args) {
+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
   __Pyx_RefNannySetupContext("_closure", 0);
@@ -23430,50 +23944,37 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":1988
+  /* "pywrapfst.pyx":2087
  * 
- *   cdef void _closure(self, bool closure_plus=False) except *:
+ *   cdef void _closure(self, bool closure_plus=False):
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def closure(self, bool closure_plus=False):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1988, __pyx_L1_error)
+    __PYX_ERR(0, 2087, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":1989
- *   cdef void _closure(self, bool closure_plus=False) except *:
- *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def closure(self, bool closure_plus=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, 1989, __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, 1989, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":1987
+  /* "pywrapfst.pyx":2086
  *     return self
  * 
- *   cdef void _closure(self, bool closure_plus=False) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
- *     self._check_mutating_imethod()
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._closure", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1991
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2089
+ *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
  *     """
@@ -23481,9 +23982,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__closure(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -23509,7 +24010,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(PyObject *__pyx_v_se
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 1991, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 2089, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23520,33 +24021,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_9closure(PyObject *__pyx_v_se
       }
     }
     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, 1991, __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, 2089, __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, 1991, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2089, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_8closure(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_closure_plus);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_8closure(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_closure_plus);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, bool __pyx_v_closure_plus) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, bool __pyx_v_closure_plus) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__closure __pyx_t_1;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":2009
+  /* "pywrapfst.pyx":2107
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -23555,26 +24056,26 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_closure");
-    __PYX_ERR(0, 2009, __pyx_L1_error)
+    __PYX_ERR(0, 2107, __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); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2009, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_closure(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2010
+  /* "pywrapfst.pyx":2108
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _concat(self, _Fst fst2) except *:
+ *   cdef void _concat(self, Fst fst2) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1991
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2089
+ *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
  *     """
@@ -23583,7 +24084,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23591,52 +24092,52 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_8closure(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2012
+/* "pywrapfst.pyx":2110
  *     return self
  * 
- *   cdef void _concat(self, _Fst fst2) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2) {
+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
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":2013
+  /* "pywrapfst.pyx":2111
  * 
- *   cdef void _concat(self, _Fst fst2) except *:
+ *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))             # <<<<<<<<<<<<<<
  *     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, 2013, __pyx_L1_error)
+    __PYX_ERR(0, 2111, __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, 2013, __pyx_L1_error)
+    __PYX_ERR(0, 2111, __pyx_L1_error)
   }
   fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_fst2->_fst));
 
-  /* "pywrapfst.pyx":2014
- *   cdef void _concat(self, _Fst fst2) except *:
+  /* "pywrapfst.pyx":2112
+ *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def concat(self, _Fst fst2):
+ *   def concat(self, Fst fst2):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2014, __pyx_L1_error)
+    __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, 2014, __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)
 
-  /* "pywrapfst.pyx":2012
+  /* "pywrapfst.pyx":2110
  *     return self
  * 
- *   cdef void _concat(self, _Fst fst2) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()
  */
@@ -23644,28 +24145,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__concat(struct __pyx_obj_9pywrapfst
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._concat", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._concat", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2016
+/* "pywrapfst.pyx":2114
  *     self._check_mutating_imethod()
  * 
- *   def concat(self, _Fst fst2):             # <<<<<<<<<<<<<<
+ *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
  *     """
  *     concat(self, fst2)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2) {
+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) {
   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, 2016, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_10concat(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_fst2));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst_Fst, 1, "fst2", 0))) __PYX_ERR(0, 2114, __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 */
   goto __pyx_L0;
@@ -23676,12 +24177,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_11concat(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2) {
+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
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":2033
+  /* "pywrapfst.pyx":2131
  *       self.
  *     """
  *     self._concat(fst2)             # <<<<<<<<<<<<<<
@@ -23690,33 +24191,33 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_concat");
-    __PYX_ERR(0, 2033, __pyx_L1_error)
+    __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, 2033, __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)
 
-  /* "pywrapfst.pyx":2034
+  /* "pywrapfst.pyx":2132
  *     """
  *     self._concat(fst2)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _connect(self) except *:
+ *   cdef void _connect(self):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2016
+  /* "pywrapfst.pyx":2114
  *     self._check_mutating_imethod()
  * 
- *   def concat(self, _Fst fst2):             # <<<<<<<<<<<<<<
+ *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
  *     """
  *     concat(self, fst2)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.concat", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.concat", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23724,62 +24225,49 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_10concat(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2036
+/* "pywrapfst.pyx":2134
  *     return self
  * 
- *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _connect(self):             # <<<<<<<<<<<<<<
  *     fst.Connect(self._mfst.get())
- *     self._check_mutating_imethod()
+ * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":2037
+  /* "pywrapfst.pyx":2135
  * 
- *   cdef void _connect(self) except *:
+ *   cdef void _connect(self):
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def connect(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2037, __pyx_L1_error)
+    __PYX_ERR(0, 2135, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2038
- *   cdef void _connect(self) except *:
- *     fst.Connect(self._mfst.get())
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def connect(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, 2038, __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, 2038, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2036
+  /* "pywrapfst.pyx":2134
  *     return self
  * 
- *   cdef void _connect(self) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _connect(self):             # <<<<<<<<<<<<<<
  *     fst.Connect(self._mfst.get())
- *     self._check_mutating_imethod()
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._connect", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._connect", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2040
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2137
+ *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
  *     """
@@ -23787,25 +24275,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__connect(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_12connect[] = "\n    connect(self)\n\n    Removes unsuccessful paths.\n\n    This operation destructively trims the FST, removing states and arcs that\n    are not part of any successful path.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_12connect[] = "\n    connect(self)\n\n    Removes unsuccessful paths.\n\n    This operation destructively trims the FST, removing states and arcs that\n    are not part of any successful path.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_13connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_12connect(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_12connect(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":2052
+  /* "pywrapfst.pyx":2149
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -23814,11 +24302,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_connect");
-    __PYX_ERR(0, 2052, __pyx_L1_error)
+    __PYX_ERR(0, 2149, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2052, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2053
+  /* "pywrapfst.pyx":2150
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
@@ -23830,8 +24318,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2040
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2137
+ *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
  *     """
@@ -23840,7 +24328,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.connect", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.connect", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23848,7 +24336,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2055
+/* "pywrapfst.pyx":2152
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -23856,11 +24344,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_12connect(struct __pyx_obj_9p
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
+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
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":2056
+  /* "pywrapfst.pyx":2153
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))             # <<<<<<<<<<<<<<
@@ -23869,15 +24357,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2056, __pyx_L1_error)
+    __PYX_ERR(0, 2153, __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, 2056, __pyx_L1_error)
+    __PYX_ERR(0, 2153, __pyx_L1_error)
   }
   fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_mapper->_mapper));
 
-  /* "pywrapfst.pyx":2057
+  /* "pywrapfst.pyx":2154
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -23886,11 +24374,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2057, __pyx_L1_error)
+    __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, 2057, __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)
 
-  /* "pywrapfst.pyx":2055
+  /* "pywrapfst.pyx":2152
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -23901,12 +24389,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._decode", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._decode", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2059
+/* "pywrapfst.pyx":2156
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -23915,14 +24403,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__decode(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
+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) {
   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, 2059, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_14decode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2156, __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 */
   goto __pyx_L0;
@@ -23933,12 +24421,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_15decode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
+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
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":2073
+  /* "pywrapfst.pyx":2170
  *       self.
  *     """
  *     self._decode(mapper)             # <<<<<<<<<<<<<<
@@ -23947,11 +24435,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_decode");
-    __PYX_ERR(0, 2073, __pyx_L1_error)
+    __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, 2073, __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)
 
-  /* "pywrapfst.pyx":2074
+  /* "pywrapfst.pyx":2171
  *     """
  *     self._decode(mapper)
  *     return self             # <<<<<<<<<<<<<<
@@ -23963,7 +24451,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2059
+  /* "pywrapfst.pyx":2156
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -23973,7 +24461,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.decode", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.decode", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -23981,7 +24469,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2076
+/* "pywrapfst.pyx":2173
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -23989,7 +24477,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_14decode(struct __pyx_obj_9py
  *             self._mfst.get().DeleteArcs(state)):
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs *__pyx_optional_args) {
+static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs *__pyx_optional_args) {
   size_t __pyx_v_n = ((size_t)0);
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -24004,7 +24492,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
   }
 
-  /* "pywrapfst.pyx":2077
+  /* "pywrapfst.pyx":2174
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24014,12 +24502,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   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, 2077, __pyx_L1_error)
+      __PYX_ERR(0, 2174, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":2078
+    /* "pywrapfst.pyx":2175
  *   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)):             # <<<<<<<<<<<<<<
@@ -24028,12 +24516,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 2078, __pyx_L1_error)
+      __PYX_ERR(0, 2175, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":2077
+  /* "pywrapfst.pyx":2174
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24043,14 +24531,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2079
+    /* "pywrapfst.pyx":2176
  *     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, 2079, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2176, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24064,14 +24552,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
     }
     __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, 2079, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2176, __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, 2079, __pyx_L1_error)
+    __PYX_ERR(0, 2176, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2077
+    /* "pywrapfst.pyx":2174
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24080,7 +24568,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":2080
+  /* "pywrapfst.pyx":2177
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24089,11 +24577,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 2080, __pyx_L1_error)
+    __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, 2080, __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)
 
-  /* "pywrapfst.pyx":2076
+  /* "pywrapfst.pyx":2173
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -24107,12 +24595,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2082
+/* "pywrapfst.pyx":2179
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24121,10 +24609,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_arcs(struct __pyx_obj_9pywr
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_16delete_arcs[] = "\n    delete_arcs(self, state, n=0)\n\n    Deletes arcs leaving a particular state.\n\n    Args:\n      state: The integer index of a state.\n      n: An optional argument indicating how many arcs to be deleted. If this\n          argument is omitted or passed as zero, all arcs from this state are\n          deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -24156,7 +24644,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2082, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2179, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24167,35 +24655,35 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2082, __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, 2179, __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, 2082, __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, 2179, __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, 2082, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2179, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, size_t __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":2100
+  /* "pywrapfst.pyx":2197
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -24204,13 +24692,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_arcs");
-    __PYX_ERR(0, 2100, __pyx_L1_error)
+    __PYX_ERR(0, 2197, __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, 2100, __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, 2197, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2101
+  /* "pywrapfst.pyx":2198
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -24222,7 +24710,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2082
+  /* "pywrapfst.pyx":2179
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24232,7 +24720,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -24240,7 +24728,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2103
+/* "pywrapfst.pyx":2200
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24248,11 +24736,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_16delete_arcs(struct __pyx_ob
  *     if states:
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states *__pyx_optional_args) {
+static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states *__pyx_optional_args) {
   PyObject *__pyx_v_states = ((PyObject *)Py_None);
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
-  std::vector<__pyx_t_10basictypes_int64>  __pyx_t_2;
+  std::vector<int64>  __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
@@ -24263,17 +24751,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2105
+  /* "pywrapfst.pyx":2202
  *   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, 2105, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2202, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2106
+    /* "pywrapfst.pyx":2203
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24282,20 +24770,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_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, 2106, __pyx_L1_error)
+      __PYX_ERR(0, 2203, __pyx_L1_error)
     }
-    __pyx_t_2 = __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2106, __pyx_L1_error)
-    __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<__pyx_t_10basictypes_int64>  const )__pyx_t_2)) != 0)) != 0);
+    __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_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<int64>  const )__pyx_t_2)) != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":2107
+      /* "pywrapfst.pyx":2204
  *     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, 2107, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2204, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_5 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24309,14 +24797,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
       }
       __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, 2107, __pyx_L1_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2204, __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, 2107, __pyx_L1_error)
+      __PYX_ERR(0, 2204, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":2106
+      /* "pywrapfst.pyx":2203
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24325,7 +24813,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
     }
 
-    /* "pywrapfst.pyx":2105
+    /* "pywrapfst.pyx":2202
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -24335,7 +24823,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":2109
+  /* "pywrapfst.pyx":2206
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -24345,13 +24833,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2109, __pyx_L1_error)
+      __PYX_ERR(0, 2206, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":2110
+  /* "pywrapfst.pyx":2207
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24360,11 +24848,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(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, 2110, __pyx_L1_error)
+    __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, 2110, __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)
 
-  /* "pywrapfst.pyx":2103
+  /* "pywrapfst.pyx":2200
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24378,12 +24866,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2112
+/* "pywrapfst.pyx":2209
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24392,9 +24880,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__delete_states(struct __pyx_obj_9py
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -24421,7 +24909,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2112, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2209, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24435,26 +24923,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_19delete_states(PyObject *__p
   }
   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, 2112, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2209, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_18delete_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_states);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_18delete_states(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_states);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_states) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_states) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states __pyx_t_1;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":2128
+  /* "pywrapfst.pyx":2225
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
@@ -24463,13 +24951,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_states");
-    __PYX_ERR(0, 2128, __pyx_L1_error)
+    __PYX_ERR(0, 2225, __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, 2128, __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, 2225, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2129
+  /* "pywrapfst.pyx":2226
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
@@ -24481,7 +24969,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2112
+  /* "pywrapfst.pyx":2209
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24491,7 +24979,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -24499,7 +24987,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2131
+/* "pywrapfst.pyx":2228
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24507,11 +24995,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_18delete_states(struct __pyx_
  *     self._check_mutating_imethod()
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
+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
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":2132
+  /* "pywrapfst.pyx":2229
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())             # <<<<<<<<<<<<<<
@@ -24520,15 +25008,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2132, __pyx_L1_error)
+    __PYX_ERR(0, 2229, __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, 2132, __pyx_L1_error)
+    __PYX_ERR(0, 2229, __pyx_L1_error)
   }
   fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_mapper->_mapper.get());
 
-  /* "pywrapfst.pyx":2133
+  /* "pywrapfst.pyx":2230
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24537,11 +25025,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__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, 2133, __pyx_L1_error)
+    __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, 2133, __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)
 
-  /* "pywrapfst.pyx":2131
+  /* "pywrapfst.pyx":2228
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24552,12 +25040,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._encode", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._encode", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2135
+/* "pywrapfst.pyx":2232
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24566,14 +25054,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__encode(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
+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) {
   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, 2135, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_20encode(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2232, __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 */
   goto __pyx_L0;
@@ -24584,12 +25072,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_21encode(PyObject *__pyx_v_se
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
+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
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":2154
+  /* "pywrapfst.pyx":2251
  *       self.
  *     """
  *     self._encode(mapper)             # <<<<<<<<<<<<<<
@@ -24598,23 +25086,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encode");
-    __PYX_ERR(0, 2154, __pyx_L1_error)
+    __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, 2154, __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)
 
-  /* "pywrapfst.pyx":2155
+  /* "pywrapfst.pyx":2252
  *     """
  *     self._encode(mapper)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _invert(self) except *:
+ *   cdef void _invert(self):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2135
+  /* "pywrapfst.pyx":2232
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24624,7 +25112,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9py
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.encode", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.encode", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -24632,62 +25120,49 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_20encode(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2157
+/* "pywrapfst.pyx":2254
  *     return self
  * 
- *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _invert(self):             # <<<<<<<<<<<<<<
  *     fst.Invert(self._mfst.get())
- *     self._check_mutating_imethod()
+ * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":2158
+  /* "pywrapfst.pyx":2255
  * 
- *   cdef void _invert(self) except *:
+ *   cdef void _invert(self):
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def invert(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2158, __pyx_L1_error)
+    __PYX_ERR(0, 2255, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2159
- *   cdef void _invert(self) except *:
- *     fst.Invert(self._mfst.get())
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def invert(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, 2159, __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, 2159, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2157
+  /* "pywrapfst.pyx":2254
  *     return self
  * 
- *   cdef void _invert(self) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _invert(self):             # <<<<<<<<<<<<<<
  *     fst.Invert(self._mfst.get())
- *     self._check_mutating_imethod()
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._invert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._invert", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2161
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2257
+ *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
  *     """
@@ -24695,25 +25170,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__invert(struct __pyx_obj_9pywrapfst
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_22invert[] = "\n    invert(self)\n\n    Inverts the FST's transduction.\n\n    This operation destructively inverts the FST's transduction by exchanging\n    input and output labels.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_22invert[] = "\n    invert(self)\n\n    Inverts the FST's transduction.\n\n    This operation destructively inverts the FST's transduction by exchanging\n    input and output labels.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_23invert(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_22invert(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_22invert(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2173
+  /* "pywrapfst.pyx":2269
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -24722,24 +25197,24 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_invert");
-    __PYX_ERR(0, 2173, __pyx_L1_error)
+    __PYX_ERR(0, 2269, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2173, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2174
+  /* "pywrapfst.pyx":2270
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _minimize(self, float delta=fst.kShortestDelta,
+ *   cdef void _minimize(self,
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2161
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2257
+ *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
  *     """
@@ -24748,7 +25223,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.invert", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.invert", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -24756,20 +25231,20 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_22invert(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2176
+/* "pywrapfst.pyx":2272
  *     return self
  * 
- *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:
- *     # This runs in-place when the second argument is null.
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__9;
+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;
 
-  /* "pywrapfst.pyx":2177
- * 
- *   cdef void _minimize(self, float delta=fst.kShortestDelta,
+  /* "pywrapfst.pyx":2274
+ *   cdef void _minimize(self,
+ *                       float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
@@ -24786,7 +25261,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2179
+  /* "pywrapfst.pyx":2276
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -24795,11 +25270,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(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, 2179, __pyx_L1_error)
+    __PYX_ERR(0, 2276, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2180
+  /* "pywrapfst.pyx":2277
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24808,27 +25283,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(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, 2180, __pyx_L1_error)
+    __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, 2180, __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)
 
-  /* "pywrapfst.pyx":2176
+  /* "pywrapfst.pyx":2272
  *     return self
  * 
- *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:
- *     # This runs in-place when the second argument is null.
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2182
+/* "pywrapfst.pyx":2279
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -24837,9 +25312,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__minimize(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_24minimize[] = "\n    minimize(self, delta=1e-6, allow_nondet=False)\n\n    Minimizes the FST.\n\n    This operation destructively performs the minimization of deterministic\n    weighted automata and transducers. If the input FST A is an acceptor, this\n    operation produces the minimal acceptor B equivalent to A, i.e. the\n    acceptor with a minimal number of states that is equivalent to A. If the\n    input FST A is a transducer, this operation internally builds an equivalent\n    transducer with a minimal number of states. However, this minimality is\n    obtained by allowing transition having strings of symbols as output labels,\n    this known in the litterature as a real-time transducer. Such transducers\n    are not directly supported by the library. This function will convert such\n    transducer by expanding each string-labeled transition into a sequence of\n    transitions. This will results in the creation of new states, hence losing\n    the minimality property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      allow_nondet: Attempt minimization of non-deterministic FST?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_24minimize[] = "\n    minimize(self, delta=1e-6, allow_nondet=False)\n\n    Minimizes the FST.\n\n    This operation destructively performs the minimization of deterministic\n    weighted automata and transducers. If the input FST A is an acceptor, this\n    operation produces the minimal acceptor B equivalent to A, i.e. the\n    acceptor with a minimal number of states that is equivalent to A. If the\n    input FST A is a transducer, this operation internally builds an equivalent\n    transducer with a minimal number of states. However, this minimality is\n    obtained by allowing transition having strings of symbols as output labels,\n    this known in the litterature as a real-time transducer. Such transducers\n    are not directly supported by the library. This function will convert such\n    transducer by expanding each string-labeled transition into a sequence of\n    transitions. This will results in the creation of new states, hence losing\n    the minimality property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      allow_nondet: Attempt minimization of non-deterministic FST?\n\n    Returns:\n      self.\n    ";
+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;
   PyObject *__pyx_r = 0;
@@ -24874,7 +25349,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2182, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2279, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24887,38 +25362,38 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_25minimize(PyObject *__pyx_v_
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2182, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2279, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__10;
+      __pyx_v_delta = __pyx_k__11;
     }
     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, 2182, __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, 2279, __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, 2182, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2279, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_24minimize(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_allow_nondet);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_24minimize(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_allow_nondet);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_allow_nondet) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize __pyx_t_1;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2208
+  /* "pywrapfst.pyx":2305
  *       self.
  *     """
  *     self._minimize(delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -24927,14 +25402,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_minimize");
-    __PYX_ERR(0, 2208, __pyx_L1_error)
+    __PYX_ERR(0, 2305, __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, 2208, __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, 2305, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2209
+  /* "pywrapfst.pyx":2306
  *     """
  *     self._minimize(delta, allow_nondet)
  *     return self             # <<<<<<<<<<<<<<
@@ -24946,7 +25421,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2182
+  /* "pywrapfst.pyx":2279
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -24956,7 +25431,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -24964,7 +25439,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2211
+/* "pywrapfst.pyx":2308
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -24972,8 +25447,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_24minimize(struct __pyx_obj_9
  *     mutable_arcs(self, state)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*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) {
   struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -24991,11 +25466,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     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, 2211, __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, 2308, __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_11_MutableFst_27mutable_arcs)) {
+      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, 2211, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2308, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -25011,10 +25486,10 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
         __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, 2211, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2308, __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, 2211, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2308, __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;
@@ -25033,7 +25508,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
     #endif
   }
 
-  /* "pywrapfst.pyx":2223
+  /* "pywrapfst.pyx":2320
  *       A MutableArcIterator.
  *     """
  *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -25041,9 +25516,9 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
  *   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, 2223, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2320, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2223, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2320, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -25051,14 +25526,14 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
   __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, 2223, __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, 2320, __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":2211
+  /* "pywrapfst.pyx":2308
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -25073,7 +25548,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -25082,36 +25557,36 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_11_Mut
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2211, __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, 2308, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("mutable_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2211, __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, 2308, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25120,7 +25595,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.mutable_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25128,7 +25603,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2225
+/* "pywrapfst.pyx":2322
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -25137,20 +25612,20 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_26mutable_arcs(struct __pyx_o
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_28mutable_input_symbols[] = "\n    mutable_input_symbols(self)\n\n    Returns the FST's (mutable) input symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_28mutable_input_symbols[] = "\n    mutable_input_symbols(self)\n\n    Returns the FST's (mutable) input symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_29mutable_input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_input_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+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
@@ -25158,7 +25633,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2231
+  /* "pywrapfst.pyx":2328
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()             # <<<<<<<<<<<<<<
@@ -25167,59 +25642,59 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2231, __pyx_L1_error)
+    __PYX_ERR(0, 2328, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableInputSymbols();
 
-  /* "pywrapfst.pyx":2232
+  /* "pywrapfst.pyx":2329
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  */
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2233
+    /* "pywrapfst.pyx":2330
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  */
     __Pyx_XDECREF(__pyx_r);
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2232
+    /* "pywrapfst.pyx":2329
  *     """
  *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  */
   }
 
-  /* "pywrapfst.pyx":2234
+  /* "pywrapfst.pyx":2331
  *     if syms == NULL:
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)             # <<<<<<<<<<<<<<
  * 
  *   def mutable_output_symbols(self):
  */
   __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, 2234, __pyx_L1_error)
+    __PYX_ERR(0, 2331, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2234, __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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2225
+  /* "pywrapfst.pyx":2322
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -25230,7 +25705,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.mutable_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.mutable_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25238,8 +25713,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2236
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+/* "pywrapfst.pyx":2333
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -25247,90 +25722,90 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_28mutable_input_symbols(struc
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_30mutable_output_symbols[] = "\n    mutable_output_symbols(self)\n\n    Returns the FST's (mutable) output symbol table, or None if none is present.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_30mutable_output_symbols[] = "\n    mutable_output_symbols(self)\n\n    Returns the FST's (mutable) output symbol table, or None if none is present.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_31mutable_output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_output_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
-  fst::SymbolTable *__pyx_v_syms;
+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;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2242
+  /* "pywrapfst.pyx":2339
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
+ *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
  *     if syms == NULL:
  *       return
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2242, __pyx_L1_error)
+    __PYX_ERR(0, 2339, __pyx_L1_error)
   }
   __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
 
-  /* "pywrapfst.pyx":2243
+  /* "pywrapfst.pyx":2340
  *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
+ *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  */
   __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2244
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
+    /* "pywrapfst.pyx":2341
+ *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:
  *       return             # <<<<<<<<<<<<<<
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  */
     __Pyx_XDECREF(__pyx_r);
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2243
+    /* "pywrapfst.pyx":2340
  *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
+ *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
  *     if syms == NULL:             # <<<<<<<<<<<<<<
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  */
   }
 
-  /* "pywrapfst.pyx":2245
+  /* "pywrapfst.pyx":2342
  *     if syms == NULL:
  *       return
- *     return _init_MutableFstSymbolTable(syms, self._mfst)             # <<<<<<<<<<<<<<
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)             # <<<<<<<<<<<<<<
  * 
  *   cpdef int64 num_states(self):
  */
   __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, 2245, __pyx_L1_error)
+    __PYX_ERR(0, 2342, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTable(__pyx_v_syms, __pyx_v_self->_mfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2245, __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_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2236
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+  /* "pywrapfst.pyx":2333
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -25340,7 +25815,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.mutable_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.mutable_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25348,23 +25823,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_30mutable_output_symbols(stru
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2247
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+/* "pywrapfst.pyx":2344
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
  *     """
  *     num_states(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int __pyx_skip_dispatch) {
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
+  int64 __pyx_t_5;
   __Pyx_RefNannySetupContext("num_states", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -25375,9 +25850,9 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(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_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2247, __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, 2344, __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_11_MutableFst_33num_states)) {
+      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);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -25391,10 +25866,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(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, 2247, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2344, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2247, __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, 2344, __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;
@@ -25413,7 +25888,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
     #endif
   }
 
-  /* "pywrapfst.pyx":2253
+  /* "pywrapfst.pyx":2350
  *     Returns the number of states.
  *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
@@ -25422,13 +25897,13 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2253, __pyx_L1_error)
+    __PYX_ERR(0, 2350, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2247
- *     return _init_MutableFstSymbolTable(syms, self._mfst)
+  /* "pywrapfst.pyx":2344
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
  *     """
@@ -25441,7 +25916,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst._MutableFst.num_states", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst.num_states", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -25449,26 +25924,26 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_11_MutableFst_num_states(st
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_32num_states[] = "\n    num_states(self)\n\n    Returns the number of states.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_32num_states[] = "\n    num_states(self)\n\n    Returns the number of states.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_33num_states(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_states (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_32num_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_32num_states(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("num_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_11_MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2247, __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, 2344, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25477,7 +25952,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.num_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.num_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25485,15 +25960,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_32num_states(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2255
+/* "pywrapfst.pyx":2352
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
- *     self._check_mutating_imethod()
+ * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__project *__pyx_optional_args) {
+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);
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_project", 0);
@@ -25503,50 +25978,37 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2256
+  /* "pywrapfst.pyx":2353
  * 
  *   cdef void _project(self, bool project_output=False) except *:
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def project(self, bool project_output=False):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2256, __pyx_L1_error)
+    __PYX_ERR(0, 2353, __pyx_L1_error)
   }
   fst::script::Project(__pyx_v_self->_mfst.get(), fst::script::GetProjectType(__pyx_v_project_output));
 
-  /* "pywrapfst.pyx":2257
- *   cdef void _project(self, bool project_output=False) except *:
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def project(self, bool project_output=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, 2257, __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, 2257, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2255
+  /* "pywrapfst.pyx":2352
  *     return self._mfst.get().NumStates()
  * 
  *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
  *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
- *     self._check_mutating_imethod()
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._project", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2259
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2355
+ *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
  *     """
@@ -25554,9 +26016,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__project(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -25582,7 +26044,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2259, __pyx_L3_error)
+        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)) {
@@ -25593,33 +26055,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_35project(PyObject *__pyx_v_s
       }
     }
     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, 2259, __pyx_L3_error)
+      __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, 2259, __pyx_L3_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_AddTraceback("pywrapfst.MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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), __pyx_v_project_output);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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, bool __pyx_v_project_output) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__project __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__project __pyx_t_1;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2275
+  /* "pywrapfst.pyx":2371
  *       self.
  *     """
  *     self._project(project_output)             # <<<<<<<<<<<<<<
@@ -25628,26 +26090,26 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_project");
-    __PYX_ERR(0, 2275, __pyx_L1_error)
+    __PYX_ERR(0, 2371, __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, 2275, __pyx_L1_error)
+  ((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)
 
-  /* "pywrapfst.pyx":2276
+  /* "pywrapfst.pyx":2372
  *     """
  *     self._project(project_output)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
+ *   cdef void _prune(self,
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2259
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2355
+ *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
  * 
  *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
  *     """
@@ -25656,7 +26118,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25664,21 +26126,21 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_34project(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2278
+/* "pywrapfst.pyx":2374
  *     return self
  * 
- *   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.
+ *   cdef void _prune(self,             # <<<<<<<<<<<<<<
+ *                    float delta=fst.kDelta,
+ *                    int64 nstate=fst.kNoStateId,
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__11;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__12;
+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;
 
-  /* "pywrapfst.pyx":2279
- * 
- *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
+  /* "pywrapfst.pyx":2377
+ *                    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(),
@@ -25700,7 +26162,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
     }
   }
 
-  /* "pywrapfst.pyx":2281
+  /* "pywrapfst.pyx":2379
  *                    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(),             # <<<<<<<<<<<<<<
@@ -25709,20 +26171,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2281, __pyx_L1_error)
+    __PYX_ERR(0, 2379, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2282
+  /* "pywrapfst.pyx":2380
  *     # 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)
  *     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, 2281, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":2283
+  /* "pywrapfst.pyx":2381
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
@@ -25731,11 +26193,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(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, 2283, __pyx_L1_error)
+    __PYX_ERR(0, 2381, __pyx_L1_error)
   }
   fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2284
+  /* "pywrapfst.pyx":2382
  *                                                        weight)
  *     fst.Prune(self._mfst.get(), wc, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25744,27 +26206,27 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(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, 2284, __pyx_L1_error)
+    __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, 2284, __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)
 
-  /* "pywrapfst.pyx":2278
+  /* "pywrapfst.pyx":2374
  *     return self
  * 
- *   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.
+ *   cdef void _prune(self,             # <<<<<<<<<<<<<<
+ *                    float delta=fst.kDelta,
+ *                    int64 nstate=fst.kNoStateId,
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2286
+/* "pywrapfst.pyx":2384
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -25773,11 +26235,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__prune(struct __pyx_obj_9pywrapfst_
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_36prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_36prune[] = "\n    prune(self, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n    Removes paths with weights below a certain threshold.\n\n    This operation deletes states and arcs in the input FST that do not belong\n    to a successful path whose weight is no more (w.r.t the natural semiring\n    order) than the threshold t \\otimes-times the weight of the shortest path in\n    the input FST. Weights must be commutative and have the path property.\n\n    Args:\n      delta: Comparison/quantization delta.\n      nstate: State number threshold.\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
+  int64 __pyx_v_nstate;
   PyObject *__pyx_v_weight = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -25786,7 +26248,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_sel
     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":2289
+    /* "pywrapfst.pyx":2387
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -25828,7 +26290,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2286, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2384, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25843,28 +26305,28 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_sel
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2287, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2385, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__13;
+      __pyx_v_delta = __pyx_k__14;
     }
     if (values[1]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2288, __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, 2386, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__14;
+      __pyx_v_nstate = __pyx_k__15;
     }
     __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, 2286, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2384, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_36prune(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
+  __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":2286
+  /* "pywrapfst.pyx":2384
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -25877,13 +26339,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_37prune(PyObject *__pyx_v_sel
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__prune __pyx_t_1;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2309
+  /* "pywrapfst.pyx":2407
  *       self.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -25892,15 +26354,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_prune");
-    __PYX_ERR(0, 2309, __pyx_L1_error)
+    __PYX_ERR(0, 2407, __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, 2309, __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, 2407, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2310
+  /* "pywrapfst.pyx":2408
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -25912,7 +26374,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2286
+  /* "pywrapfst.pyx":2384
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -25922,7 +26384,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -25930,7 +26392,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2312
+/* "pywrapfst.pyx":2410
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -25938,22 +26400,22 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_36prune(struct __pyx_obj_9pyw
  *                   bool remove_total_weight=False,
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__push *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__15;
+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;
 
-  /* "pywrapfst.pyx":2314
+  /* "pywrapfst.pyx":2412
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
- *                   bool to_final=False) except *:
+ *                   bool to_final=False):
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2315
+  /* "pywrapfst.pyx":2413
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
- *                   bool to_final=False) except *:             # <<<<<<<<<<<<<<
+ *                   bool to_final=False):             # <<<<<<<<<<<<<<
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)
  */
@@ -25972,41 +26434,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
     }
   }
 
-  /* "pywrapfst.pyx":2316
+  /* "pywrapfst.pyx":2414
  *                   bool remove_total_weight=False,
- *                   bool to_final=False) except *:
+ *                   bool to_final=False):
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,             # <<<<<<<<<<<<<<
  *              remove_total_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, 2316, __pyx_L1_error)
+    __PYX_ERR(0, 2414, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2317
- *                   bool to_final=False) except *:
+  /* "pywrapfst.pyx":2415
+ *                   bool to_final=False):
  *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
- * 
- */
-  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":2318
- *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
- *              remove_total_weight)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
  *   def push(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, 2318, __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, 2318, __pyx_L1_error)
+  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":2312
+  /* "pywrapfst.pyx":2410
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -26017,13 +26466,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._push", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._push", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2320
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2417
+ *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
  *            float delta=fst.kShortestDelta,
@@ -26031,9 +26480,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__push(struct __pyx_obj_9pywrapfst__
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_38push[] = "\n    push(self, delta=1-e6, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_38push[] = "\n    push(self, delta=1-e6, remove_total_weight=False, to_final=False)\n\n    Pushes weights towards the initial or final states.\n\n    This operation destructively produces an equivalent transducer by pushing\n    the weights towards the initial state or toward the final states. When\n    pushing weights towards the initial state, the sum of the weight of the\n    outgoing transitions and final weight at any non-initial state is equal to\n    one in the resulting machine. When pushing weights towards the final states,\n    the sum of the weight of the incoming transitions at any state is equal to\n    one. Weights need to be left distributive when pushing towards the initial\n    state and right distributive when pushing towards the final states.\n\n    Args:\n      delta: Comparison/quantization delta.\n      remove_total_weight: If pushing weights, should the total weight be\n          removed?\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   bool __pyx_v_remove_total_weight;
   bool __pyx_v_to_final;
@@ -26077,7 +26526,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2320, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2417, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26092,15 +26541,15 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2321, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2418, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__16;
+      __pyx_v_delta = __pyx_k__17;
     }
     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, 2322, __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, 2419, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2322
+      /* "pywrapfst.pyx":2419
  *   def push(self,
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -26110,10 +26559,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2323, __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, 2420, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2323
+      /* "pywrapfst.pyx":2420
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26125,16 +26574,16 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2320, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2417, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_38push(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
+  __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":2320
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2417
+ *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
  *            float delta=fst.kShortestDelta,
@@ -26146,13 +26595,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_39push(PyObject *__pyx_v_self
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__push __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__push __pyx_t_1;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2347
+  /* "pywrapfst.pyx":2444
  *       self.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
@@ -26161,15 +26610,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_push");
-    __PYX_ERR(0, 2347, __pyx_L1_error)
+    __PYX_ERR(0, 2444, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.remove_total_weight = __pyx_v_remove_total_weight;
   __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); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2347, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_push(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2348
+  /* "pywrapfst.pyx":2445
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -26181,8 +26630,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2320
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2417
+ *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
  *            float delta=fst.kShortestDelta,
@@ -26191,7 +26640,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -26199,7 +26648,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2350
+/* "pywrapfst.pyx":2447
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -26207,15 +26656,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_38push(struct __pyx_obj_9pywr
  *     _ipairs.reset(new vector[fst.LabelPair]())
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs *__pyx_optional_args) {
+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_3fst_LabelPair> >  __pyx_v__ipairs;
-  std::unique_ptr<std::vector<__pyx_t_3fst_LabelPair> >  __pyx_v__opairs;
-  __pyx_t_10basictypes_int64 __pyx_v_before;
-  __pyx_t_10basictypes_int64 __pyx_v_after;
+  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;
   __Pyx_RefNannyDeclarations
-  std::vector<__pyx_t_3fst_LabelPair>  *__pyx_t_1;
+  std::vector<__pyx_t_10cpywrapfst_LabelPair>  *__pyx_t_1;
   int __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
   Py_ssize_t __pyx_t_4;
@@ -26225,9 +26674,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   PyObject *__pyx_t_8 = NULL;
   PyObject *__pyx_t_9 = NULL;
   PyObject *(*__pyx_t_10)(PyObject *);
-  __pyx_t_10basictypes_int64 __pyx_t_11;
-  __pyx_t_10basictypes_int64 __pyx_t_12;
-  __pyx_t_3fst_LabelPair __pyx_t_13;
+  int64 __pyx_t_11;
+  int64 __pyx_t_12;
+  __pyx_t_10cpywrapfst_LabelPair __pyx_t_13;
   int __pyx_t_14;
   __Pyx_RefNannySetupContext("_relabel_pairs", 0);
   if (__pyx_optional_args) {
@@ -26239,7 +26688,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2352
+  /* "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]())             # <<<<<<<<<<<<<<
@@ -26247,14 +26696,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  *     _opairs.reset(new vector[fst.LabelPair]())
  */
   try {
-    __pyx_t_1 = new std::vector<__pyx_t_3fst_LabelPair> ();
+    __pyx_t_1 = new std::vector<__pyx_t_10cpywrapfst_LabelPair> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2352, __pyx_L1_error)
+    __PYX_ERR(0, 2449, __pyx_L1_error)
   }
   __pyx_v__ipairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2354
+  /* "pywrapfst.pyx":2451
  *     _ipairs.reset(new vector[fst.LabelPair]())
  *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
  *     _opairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
@@ -26262,24 +26711,24 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  *     cdef int64 after
  */
   try {
-    __pyx_t_1 = new std::vector<__pyx_t_3fst_LabelPair> ();
+    __pyx_t_1 = new std::vector<__pyx_t_10cpywrapfst_LabelPair> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2354, __pyx_L1_error)
+    __PYX_ERR(0, 2451, __pyx_L1_error)
   }
   __pyx_v__opairs.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2357
+  /* "pywrapfst.pyx":2454
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2357, __pyx_L1_error)
+  __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) {
 
-    /* "pywrapfst.pyx":2358
+    /* "pywrapfst.pyx":2455
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -26290,26 +26739,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
       __pyx_t_3 = __pyx_v_ipairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
       __pyx_t_5 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2358, __pyx_L1_error)
+      __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, 2358, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2455, __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 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, 2358, __pyx_L1_error)
+          __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)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2358, __pyx_L1_error)
+          __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);
           #endif
         } else {
           if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) 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, 2358, __pyx_L1_error)
+          __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)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2358, __pyx_L1_error)
+          __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);
           #endif
         }
@@ -26319,7 +26768,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2358, __pyx_L1_error)
+            else __PYX_ERR(0, 2455, __pyx_L1_error)
           }
           break;
         }
@@ -26331,7 +26780,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2358, __pyx_L1_error)
+          __PYX_ERR(0, 2455, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -26344,15 +26793,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __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, 2358, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2455, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2358, __pyx_L1_error)
+        __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;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2358, __pyx_L1_error)
+        __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;
@@ -26360,7 +26809,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __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_GOTREF(__pyx_t_8);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2358, __pyx_L1_error)
+        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;
         goto __pyx_L7_unpacking_done;
@@ -26368,17 +26817,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_10 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2358, __pyx_L1_error)
+        __PYX_ERR(0, 2455, __pyx_L1_error)
         __pyx_L7_unpacking_done:;
       }
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2358, __pyx_L1_error)
+      __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2358, __pyx_L1_error)
+      __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;
 
-      /* "pywrapfst.pyx":2359
+      /* "pywrapfst.pyx":2456
  *     if ipairs:
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -26386,19 +26835,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  *       for (before, after) in opairs:
  */
       try {
-        __pyx_t_13 = __pyx_t_3fst_LabelPair(__pyx_v_before, __pyx_v_after);
+        __pyx_t_13 = __pyx_t_10cpywrapfst_LabelPair(__pyx_v_before, __pyx_v_after);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2359, __pyx_L1_error)
+        __PYX_ERR(0, 2456, __pyx_L1_error)
       }
       try {
         __pyx_v__ipairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2359, __pyx_L1_error)
+        __PYX_ERR(0, 2456, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2358
+      /* "pywrapfst.pyx":2455
  *     cdef int64 after
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
@@ -26408,7 +26857,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2357
+    /* "pywrapfst.pyx":2454
  *     cdef int64 before
  *     cdef int64 after
  *     if ipairs:             # <<<<<<<<<<<<<<
@@ -26417,17 +26866,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2360
+  /* "pywrapfst.pyx":2457
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2360, __pyx_L1_error)
+  __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) {
 
-    /* "pywrapfst.pyx":2361
+    /* "pywrapfst.pyx":2458
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -26438,26 +26887,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
       __pyx_t_3 = __pyx_v_opairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
       __pyx_t_5 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2361, __pyx_L1_error)
+      __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, 2361, __pyx_L1_error)
+      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2458, __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 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, 2361, __pyx_L1_error)
+          __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)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2361, __pyx_L1_error)
+          __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);
           #endif
         } else {
           if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) 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, 2361, __pyx_L1_error)
+          __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)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2361, __pyx_L1_error)
+          __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);
           #endif
         }
@@ -26467,7 +26916,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2361, __pyx_L1_error)
+            else __PYX_ERR(0, 2458, __pyx_L1_error)
           }
           break;
         }
@@ -26479,7 +26928,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2361, __pyx_L1_error)
+          __PYX_ERR(0, 2458, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
@@ -26492,15 +26941,15 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_INCREF(__pyx_t_8);
         __Pyx_INCREF(__pyx_t_7);
         #else
-        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2361, __pyx_L1_error)
+        __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, 2361, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2458, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
         #endif
         __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2361, __pyx_L1_error)
+        __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;
@@ -26508,7 +26957,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __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_GOTREF(__pyx_t_7);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2361, __pyx_L1_error)
+        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;
         goto __pyx_L12_unpacking_done;
@@ -26516,17 +26965,17 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_10 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2361, __pyx_L1_error)
+        __PYX_ERR(0, 2458, __pyx_L1_error)
         __pyx_L12_unpacking_done:;
       }
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2361, __pyx_L1_error)
+      __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2361, __pyx_L1_error)
+      __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;
 
-      /* "pywrapfst.pyx":2362
+      /* "pywrapfst.pyx":2459
  *     if opairs:
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
@@ -26534,19 +26983,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  *       raise FstArgError("No relabeling pairs specified")
  */
       try {
-        __pyx_t_13 = __pyx_t_3fst_LabelPair(__pyx_v_before, __pyx_v_after);
+        __pyx_t_13 = __pyx_t_10cpywrapfst_LabelPair(__pyx_v_before, __pyx_v_after);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2362, __pyx_L1_error)
+        __PYX_ERR(0, 2459, __pyx_L1_error)
       }
       try {
         __pyx_v__opairs.get()->push_back(__pyx_t_13);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2362, __pyx_L1_error)
+        __PYX_ERR(0, 2459, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2361
+      /* "pywrapfst.pyx":2458
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
@@ -26556,7 +27005,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2360
+    /* "pywrapfst.pyx":2457
  *       for (before, after) in ipairs:
  *         _ipairs.get().push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
@@ -26565,7 +27014,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2363
+  /* "pywrapfst.pyx":2460
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -26583,14 +27032,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __pyx_L14_bool_binop_done:;
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2364
+    /* "pywrapfst.pyx":2461
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():
  *       raise FstArgError("No relabeling pairs specified")             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2364, __pyx_L1_error)
+    __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))) {
@@ -26604,14 +27053,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
     }
     __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, 2364, __pyx_L1_error)
+    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, 2364, __pyx_L1_error)
+    __PYX_ERR(0, 2461, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2363
+    /* "pywrapfst.pyx":2460
  *       for (before, after) in opairs:
  *         _opairs.get().push_back(fst.LabelPair(before, after))
  *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
@@ -26620,7 +27069,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2365
+  /* "pywrapfst.pyx":2462
  *     if _ipairs.get().empty() and _opairs.get().empty():
  *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))             # <<<<<<<<<<<<<<
@@ -26629,11 +27078,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(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, 2365, __pyx_L1_error)
+    __PYX_ERR(0, 2462, __pyx_L1_error)
   }
   fst::script::Relabel(__pyx_v_self->_mfst.get(), (*__pyx_v__ipairs), (*__pyx_v__opairs));
 
-  /* "pywrapfst.pyx":2366
+  /* "pywrapfst.pyx":2463
  *       raise FstArgError("No relabeling pairs specified")
  *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -26642,11 +27091,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(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, 2366, __pyx_L1_error)
+    __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, 2366, __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)
 
-  /* "pywrapfst.pyx":2350
+  /* "pywrapfst.pyx":2447
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
@@ -26662,12 +27111,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
   __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_AddTraceback("pywrapfst.MutableFst._relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2368
+/* "pywrapfst.pyx":2465
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -26676,9 +27125,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_pairs(struct __pyx_obj_9py
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_40relabel_pairs[] = "\n    relabel_pairs(self, ipairs=None, opairs=None)\n\n    Replaces input and/or output labels using pairs of labels.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using pairs of the form (old_ID, new_ID); omitted indices are\n    identity-mapped.\n\n    Args:\n      ipairs: An iterable containing (older index, newer index) integer pairs.\n      opairs: An iterable containing (older index, newer index) integer pairs.\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No relabeling pairs specified.\n    ";
+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;
   PyObject *__pyx_r = 0;
@@ -26715,7 +27164,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2368, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2465, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26732,26 +27181,26 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs(PyObject *__p
   }
   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, 2368, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2465, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_ipairs, __pyx_v_opairs);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_ipairs, __pyx_v_opairs);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2388
+  /* "pywrapfst.pyx":2485
  *       FstArgError: No relabeling pairs specified.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
@@ -26760,14 +27209,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_pairs");
-    __PYX_ERR(0, 2388, __pyx_L1_error)
+    __PYX_ERR(0, 2485, __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, 2388, __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, 2485, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2389
+  /* "pywrapfst.pyx":2486
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -26779,7 +27228,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2368
+  /* "pywrapfst.pyx":2465
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -26789,7 +27238,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -26797,7 +27246,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2391
+/* "pywrapfst.pyx":2488
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -26805,9 +27254,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_40relabel_pairs(struct __pyx_
  *                             _SymbolTable new_isymbols=None,
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables *__pyx_optional_args) {
+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":2392
+  /* "pywrapfst.pyx":2489
  * 
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26816,7 +27265,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":2393
+  /* "pywrapfst.pyx":2490
  *   cdef void _relabel_tables(self,
  *                             _SymbolTable old_isymbols=None,
  *                             _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -26826,7 +27275,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   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);
 
-  /* "pywrapfst.pyx":2395
+  /* "pywrapfst.pyx":2492
  *                             _SymbolTable new_isymbols=None,
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -26835,7 +27284,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2396
+  /* "pywrapfst.pyx":2493
  *                             unknown_isymbol=b"",
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26844,7 +27293,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-  /* "pywrapfst.pyx":2397
+  /* "pywrapfst.pyx":2494
  *                             bool attach_new_isymbols=True,
  *                             _SymbolTable old_osymbols=None,
  *                             _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -26854,7 +27303,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   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);
 
-  /* "pywrapfst.pyx":2399
+  /* "pywrapfst.pyx":2496
  *                             _SymbolTable new_osymbols=None,
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
@@ -26873,7 +27322,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  fst::SymbolTable *__pyx_t_7;
+  fst::SymbolTable const *__pyx_t_7;
   std::string __pyx_t_8;
   std::string __pyx_t_9;
   __Pyx_RefNannySetupContext("_relabel_tables", 0);
@@ -26904,7 +27353,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
   }
 
-  /* "pywrapfst.pyx":2400
+  /* "pywrapfst.pyx":2497
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -26924,14 +27373,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __pyx_L4_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2401
+    /* "pywrapfst.pyx":2498
  *                             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, 2401, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2498, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -26945,14 +27394,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
     }
     __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, 2401, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2498, __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, 2401, __pyx_L1_error)
+    __PYX_ERR(0, 2498, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2400
+    /* "pywrapfst.pyx":2497
  *                             unknown_osymbol=b"",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
@@ -26961,226 +27410,226 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":2402
+  /* "pywrapfst.pyx":2499
  *     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:
- *       _old_isymbols = old_isymbols._table
+ *       _old_isymbols = old_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, 2402, __pyx_L1_error)
+    __PYX_ERR(0, 2499, __pyx_L1_error)
   }
   __pyx_v__old_isymbols = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":2403
+  /* "pywrapfst.pyx":2500
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
- *       _old_isymbols = old_isymbols._table
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  */
   __pyx_t_1 = (((PyObject *)__pyx_v_old_isymbols) != Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2404
+    /* "pywrapfst.pyx":2501
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:
- *       _old_isymbols = old_isymbols._table             # <<<<<<<<<<<<<<
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2404, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 2501, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_v_old_isymbols->_table;
+    __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_v__old_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2403
+    /* "pywrapfst.pyx":2500
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
- *       _old_isymbols = old_isymbols._table
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  */
   }
 
-  /* "pywrapfst.pyx":2405
+  /* "pywrapfst.pyx":2502
  *     if old_isymbols is not None:
- *       _old_isymbols = old_isymbols._table
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
  *     if old_osymbols is not None:
- *        _old_osymbols = old_osymbols._table
+ *        _old_osymbols = old_osymbols._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, 2405, __pyx_L1_error)
+    __PYX_ERR(0, 2502, __pyx_L1_error)
   }
   __pyx_v__old_osymbols = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":2406
- *       _old_isymbols = old_isymbols._table
+  /* "pywrapfst.pyx":2503
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
- *        _old_osymbols = old_osymbols._table
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  */
   __pyx_t_2 = (((PyObject *)__pyx_v_old_osymbols) != Py_None);
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2407
+    /* "pywrapfst.pyx":2504
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:
- *        _old_osymbols = old_osymbols._table             # <<<<<<<<<<<<<<
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2407, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 2504, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_v_old_osymbols->_table;
+    __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_v__old_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2406
- *       _old_isymbols = old_isymbols._table
+    /* "pywrapfst.pyx":2503
+ *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
- *        _old_osymbols = old_osymbols._table
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":2408
+  /* "pywrapfst.pyx":2505
  *     if old_osymbols is not None:
- *        _old_osymbols = old_osymbols._table
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL             # <<<<<<<<<<<<<<
  *     if new_isymbols is not None:
- *       _new_isymbols = new_isymbols._table
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  */
   __pyx_v__new_isymbols = NULL;
 
-  /* "pywrapfst.pyx":2409
- *        _old_osymbols = old_osymbols._table
+  /* "pywrapfst.pyx":2506
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
- *       _new_isymbols = new_isymbols._table
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  */
   __pyx_t_1 = (((PyObject *)__pyx_v_new_isymbols) != Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2410
+    /* "pywrapfst.pyx":2507
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:
- *       _new_isymbols = new_isymbols._table             # <<<<<<<<<<<<<<
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_new_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2410, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 2507, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_v_new_isymbols->_table;
+    __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_v__new_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2409
- *        _old_osymbols = old_osymbols._table
+    /* "pywrapfst.pyx":2506
+ *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
- *       _new_isymbols = new_isymbols._table
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":2411
+  /* "pywrapfst.pyx":2508
  *     if new_isymbols is not None:
- *       _new_isymbols = new_isymbols._table
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL             # <<<<<<<<<<<<<<
  *     if new_osymbols is not None:
- *       _new_osymbols = new_osymbols._table
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  */
   __pyx_v__new_osymbols = NULL;
 
-  /* "pywrapfst.pyx":2412
- *       _new_isymbols = new_isymbols._table
+  /* "pywrapfst.pyx":2509
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
- *       _new_osymbols = new_osymbols._table
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),
  */
   __pyx_t_2 = (((PyObject *)__pyx_v_new_osymbols) != Py_None);
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2413
+    /* "pywrapfst.pyx":2510
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
- *       _new_osymbols = new_osymbols._table             # <<<<<<<<<<<<<<
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     fst.Relabel(self._mfst.get(),
  *         _old_isymbols,
  */
     if (unlikely(((PyObject *)__pyx_v_new_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 2413, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 2510, __pyx_L1_error)
     }
-    __pyx_t_7 = __pyx_v_new_osymbols->_table;
+    __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_v__new_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2412
- *       _new_isymbols = new_isymbols._table
+    /* "pywrapfst.pyx":2509
+ *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
- *       _new_osymbols = new_osymbols._table
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),
  */
   }
 
-  /* "pywrapfst.pyx":2414
+  /* "pywrapfst.pyx":2511
  *     if new_osymbols is not None:
- *       _new_osymbols = new_osymbols._table
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
  *         _old_isymbols,
  *         _new_isymbols,
  */
   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, 2511, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2417
+  /* "pywrapfst.pyx":2514
  *         _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, 2417, __pyx_L1_error)
+  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2514, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2421
+  /* "pywrapfst.pyx":2518
  *         _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, 2421, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2518, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2414
+  /* "pywrapfst.pyx":2511
  *     if new_osymbols is not None:
- *       _new_osymbols = new_osymbols._table
+ *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
  *         _old_isymbols,
  *         _new_isymbols,
  */
   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":2423
+  /* "pywrapfst.pyx":2520
  *         tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27189,11 +27638,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2423, __pyx_L1_error)
+    __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, 2423, __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)
 
-  /* "pywrapfst.pyx":2391
+  /* "pywrapfst.pyx":2488
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27207,12 +27656,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2425
+/* "pywrapfst.pyx":2522
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27221,9 +27670,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__relabel_tables(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+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;
   PyObject *__pyx_v_unknown_isymbol = 0;
@@ -27239,7 +27688,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
     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":2426
+    /* "pywrapfst.pyx":2523
  * 
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27248,7 +27697,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  */
     values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2427
+    /* "pywrapfst.pyx":2524
  *   def relabel_tables(self,
  *                      _SymbolTable old_isymbols=None,
  *                      _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
@@ -27258,7 +27707,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
     values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
     values[2] = ((PyObject *)__pyx_kp_b__8);
 
-    /* "pywrapfst.pyx":2430
+    /* "pywrapfst.pyx":2527
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27267,7 +27716,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
  */
     values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":2431
+    /* "pywrapfst.pyx":2528
  *                      bool attach_new_isymbols=True,
  *                      _SymbolTable old_osymbols=None,
  *                      _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
@@ -27350,7 +27799,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2425, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2522, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27378,10 +27827,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
     __pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)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, 2429, __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, 2526, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2429
+      /* "pywrapfst.pyx":2526
  *                      _SymbolTable new_isymbols=None,
  *                      unknown_isymbol=b"",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
@@ -27394,10 +27843,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
     __pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)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, 2433, __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, 2530, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2433
+      /* "pywrapfst.pyx":2530
  *                      _SymbolTable new_osymbols=None,
  *                      unknown_osymbol=b"",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
@@ -27409,19 +27858,19 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
   }
   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, 2425, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2522, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __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, 2426, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2427, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2430, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2431, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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);
+  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)
+  __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":2425
+  /* "pywrapfst.pyx":2522
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27438,13 +27887,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables(PyObject *__
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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__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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables __pyx_t_1;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2467
+  /* "pywrapfst.pyx":2564
  *       FstArgError: No SymbolTable specified.
  *     """
  *     self._relabel_tables(old_isymbols,             # <<<<<<<<<<<<<<
@@ -27453,10 +27902,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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, 2467, __pyx_L1_error)
+    __PYX_ERR(0, 2564, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2474
+  /* "pywrapfst.pyx":2571
  *                          new_osymbols,
  *                          unknown_osymbol,
  *                          attach_new_osymbols)             # <<<<<<<<<<<<<<
@@ -27472,9 +27921,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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, 2467, __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, 2564, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2475
+  /* "pywrapfst.pyx":2572
  *                          unknown_osymbol,
  *                          attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -27486,7 +27935,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2425
+  /* "pywrapfst.pyx":2522
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
@@ -27496,7 +27945,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27504,7 +27953,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2477
+/* "pywrapfst.pyx":2574
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -27512,7 +27961,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_42relabel_tables(struct __pyx
  *       raise FstIndexError("State index out of range")
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
+static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, size_t __pyx_v_n) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -27520,7 +27969,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2478
+  /* "pywrapfst.pyx":2575
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -27529,19 +27978,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(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, 2478, __pyx_L1_error)
+    __PYX_ERR(0, 2575, __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":2479
+    /* "pywrapfst.pyx":2576
  *   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, 2479, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2576, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -27555,14 +28004,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
     }
     __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, 2479, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2576, __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, 2479, __pyx_L1_error)
+    __PYX_ERR(0, 2576, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2478
+    /* "pywrapfst.pyx":2575
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -27571,7 +28020,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
   }
 
-  /* "pywrapfst.pyx":2480
+  /* "pywrapfst.pyx":2577
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27580,11 +28029,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(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, 2480, __pyx_L1_error)
+    __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, 2480, __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)
 
-  /* "pywrapfst.pyx":2477
+  /* "pywrapfst.pyx":2574
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -27598,12 +28047,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2482
+/* "pywrapfst.pyx":2579
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -27612,10 +28061,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_arcs(struct __pyx_obj_9pyw
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_44reserve_arcs[] = "\n    reserve_arcs(self, state, n)\n\n    Reserve n arcs at a particular state (best effort).\n\n    Args:\n      state: The integer index of a state.\n      n: The number of arcs to reserve.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -27643,11 +28092,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__py
         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, 2482, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2579, __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, 2482, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2579, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -27655,30 +28104,30 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs(PyObject *__py
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2482, __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, 2482, __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, 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)
   }
   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, 2482, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2579, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_n);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, size_t __pyx_v_n) {
+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
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2498
+  /* "pywrapfst.pyx":2595
  *       FstIndexError: State index out of range.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -27687,23 +28136,23 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_arcs");
-    __PYX_ERR(0, 2498, __pyx_L1_error)
+    __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, 2498, __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)
 
-  /* "pywrapfst.pyx":2499
+  /* "pywrapfst.pyx":2596
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _reserve_states(self, int64 n) except *:
+ *   cdef void _reserve_states(self, int64 n):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2482
+  /* "pywrapfst.pyx":2579
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -27713,7 +28162,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27721,62 +28170,49 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_44reserve_arcs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2501
+/* "pywrapfst.pyx":2598
  *     return self
  * 
- *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
  *     self._mfst.get().ReserveStates(n)
- *     self._check_mutating_imethod()
+ * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n) {
+static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_n) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2502
+  /* "pywrapfst.pyx":2599
  * 
- *   cdef void _reserve_states(self, int64 n) except *:
+ *   cdef void _reserve_states(self, int64 n):
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def reserve_states(self, int64 n):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2502, __pyx_L1_error)
+    __PYX_ERR(0, 2599, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2503
- *   cdef void _reserve_states(self, int64 n) except *:
- *     self._mfst.get().ReserveStates(n)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def reserve_states(self, int64 n):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2503, __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, 2503, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2501
+  /* "pywrapfst.pyx":2598
  *     return self
  * 
- *   cdef void _reserve_states(self, int64 n) except *:             # <<<<<<<<<<<<<<
+ *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
  *     self._mfst.get().ReserveStates(n)
- *     self._check_mutating_imethod()
+ * 
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2505
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2601
+ *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
  *     """
@@ -27784,35 +28220,35 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reserve_states(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
-  __pyx_t_10basictypes_int64 __pyx_v_n;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2505, __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, 2601, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_n));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_46reserve_states(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((int64)__pyx_v_n));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_n) {
+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
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2517
+  /* "pywrapfst.pyx":2613
  *       self.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
@@ -27821,11 +28257,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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, 2517, __pyx_L1_error)
+    __PYX_ERR(0, 2613, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2517, __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":2518
+  /* "pywrapfst.pyx":2614
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -27837,8 +28273,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2505
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2601
+ *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
  *     """
@@ -27847,7 +28283,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -27855,7 +28291,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2520
+/* "pywrapfst.pyx":2616
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -27863,7 +28299,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_46reserve_states(struct __pyx
  *     _potentials.reset(new vector[fst.WeightClass]())
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight *__pyx_optional_args) {
+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;
@@ -27882,7 +28318,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2522
+  /* "pywrapfst.pyx":2618
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -27893,11 +28329,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2522, __pyx_L1_error)
+    __PYX_ERR(0, 2618, __pyx_L1_error)
   }
   __pyx_v__potentials.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":2523
+  /* "pywrapfst.pyx":2619
  *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()             # <<<<<<<<<<<<<<
@@ -27906,11 +28342,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2523, __pyx_L1_error)
+    __PYX_ERR(0, 2619, __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":2524
+  /* "pywrapfst.pyx":2620
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -27921,26 +28357,26 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __pyx_t_2 = __pyx_v_potentials; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
     __pyx_t_4 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2524, __pyx_L1_error)
+    __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, 2524, __pyx_L1_error)
+    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2620, __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 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, 2524, __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, 2620, __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, 2524, __pyx_L1_error)
+        __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);
         #endif
       } else {
         if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) 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, 2524, __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, 2620, __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, 2524, __pyx_L1_error)
+        __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);
         #endif
       }
@@ -27950,7 +28386,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2524, __pyx_L1_error)
+          else __PYX_ERR(0, 2620, __pyx_L1_error)
         }
         break;
       }
@@ -27959,7 +28395,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
     __Pyx_XDECREF_SET(__pyx_v_weight, __pyx_t_5);
     __pyx_t_5 = 0;
 
-    /* "pywrapfst.pyx":2525
+    /* "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(),             # <<<<<<<<<<<<<<
@@ -27968,19 +28404,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 2525, __pyx_L1_error)
+      __PYX_ERR(0, 2621, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2526
+    /* "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, 2525, __pyx_L1_error)
+    __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":2525
+    /* "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(),             # <<<<<<<<<<<<<<
@@ -27991,10 +28427,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
       __pyx_v__potentials.get()->push_back(__pyx_t_6);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2525, __pyx_L1_error)
+      __PYX_ERR(0, 2621, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2524
+    /* "pywrapfst.pyx":2620
  *     _potentials.reset(new vector[fst.WeightClass]())
  *     cdef string weight_type = self.weight_type()
  *     for weight in potentials:             # <<<<<<<<<<<<<<
@@ -28004,7 +28440,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   }
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2527
+  /* "pywrapfst.pyx":2623
  *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),             # <<<<<<<<<<<<<<
@@ -28013,10 +28449,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2527, __pyx_L1_error)
+    __PYX_ERR(0, 2623, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2528
+  /* "pywrapfst.pyx":2624
  *                                                             weight))
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
@@ -28025,7 +28461,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
   fst::script::Reweight(__pyx_v_self->_mfst.get(), (*__pyx_v__potentials), fst::script::GetReweightType(__pyx_v_to_final));
 
-  /* "pywrapfst.pyx":2529
+  /* "pywrapfst.pyx":2625
  *     fst.Reweight(self._mfst.get(), deref(_potentials),
  *                  fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28034,11 +28470,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(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, 2529, __pyx_L1_error)
+    __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, 2529, __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)
 
-  /* "pywrapfst.pyx":2520
+  /* "pywrapfst.pyx":2616
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
@@ -28051,13 +28487,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_weight);
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2531
+/* "pywrapfst.pyx":2627
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28066,9 +28502,9 @@ static void __pyx_f_9pywrapfst_11_MutableFst__reweight(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_48reweight[] = "\n    reweight(self, potentials, to_final=False)\n\n    Reweights an FST using an iterable of potentials.\n\n    This operation destructively reweights an FST according to the potentials\n    and in the direction specified by the user. An arc of weight w, with an\n    origin state of potential p and destination state of potential q, is\n    reweighted by p^{-1} \\otimes (w \\otimes q) when reweighting towards the\n    initial state, and by (p \\otimes w) \\otimes q^{-1} when reweighting towards\n    the final states. The weights must be left distributive when reweighting\n    towards the initial state and right distributive when reweighting towards\n    the final states (e.g., TropicalWeight and LogWeight).\n\n    Args:\n      potentials: An iterable of Weight or weight strings.\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_48reweight[] = "\n    reweight(self, potentials, to_final=False)\n\n    Reweights an FST using an iterable of potentials.\n\n    This operation destructively reweights an FST according to the potentials\n    and in the direction specified by the user. An arc of weight w, with an\n    origin state of potential p and destination state of potential q, is\n    reweighted by p^{-1} \\otimes (w \\otimes q) when reweighting towards the\n    initial state, and by (p \\otimes w) \\otimes q^{-1} when reweighting towards\n    the final states. The weights must be left distributive when reweighting\n    towards the initial state and right distributive when reweighting towards\n    the final states (e.g., TropicalWeight and LogWeight).\n\n    Args:\n      potentials: An iterable of Weight or weight strings.\n      to_final: Push towards final states?\n\n    Returns:\n      self.\n    ";
+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;
   PyObject *__pyx_r = 0;
@@ -28101,7 +28537,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2531, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2627, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28114,33 +28550,33 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_49reweight(PyObject *__pyx_v_
     }
     __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, 2531, __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, 2627, __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, 2531, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2627, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_48reweight(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_potentials, __pyx_v_to_final);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_48reweight(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_potentials, __pyx_v_to_final);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight __pyx_t_1;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2553
+  /* "pywrapfst.pyx":2649
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -28149,13 +28585,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reweight");
-    __PYX_ERR(0, 2553, __pyx_L1_error)
+    __PYX_ERR(0, 2649, __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, 2553, __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, 2649, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2554
+  /* "pywrapfst.pyx":2650
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -28167,7 +28603,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2531
+  /* "pywrapfst.pyx":2627
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28177,7 +28613,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -28185,7 +28621,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2556
+/* "pywrapfst.pyx":2652
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28193,10 +28629,10 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_48reweight(struct __pyx_obj_9
  *                        bool connect=True,
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args) {
+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);
 
-  /* "pywrapfst.pyx":2558
+  /* "pywrapfst.pyx":2654
  *   cdef void _rmepsilon(self,
  *                        queue_type=b"auto",
  *                        bool connect=True,             # <<<<<<<<<<<<<<
@@ -28205,7 +28641,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   bool __pyx_v_connect = ((bool)1);
 
-  /* "pywrapfst.pyx":2559
+  /* "pywrapfst.pyx":2655
  *                        queue_type=b"auto",
  *                        bool connect=True,
  *                        weight=None,             # <<<<<<<<<<<<<<
@@ -28213,8 +28649,8 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  *                        float delta=fst.kShortestDelta) except *:
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__17;
-  float __pyx_v_delta = __pyx_k__18;
+  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;
   __Pyx_RefNannyDeclarations
@@ -28240,7 +28676,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2562
+  /* "pywrapfst.pyx":2658
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
@@ -28249,30 +28685,30 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2562, __pyx_L1_error)
+    __PYX_ERR(0, 2658, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2563
+  /* "pywrapfst.pyx":2659
  *                        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, 2562, __pyx_L1_error)
+  __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":2565
+  /* "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, 2565, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2565, __pyx_L1_error)
+  __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":2569
+  /* "pywrapfst.pyx":2665
  *                                         wc,
  *                                         nstate,
  *                                         delta))             # <<<<<<<<<<<<<<
@@ -28281,7 +28717,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   __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":2570
+  /* "pywrapfst.pyx":2666
  *                                         nstate,
  *                                         delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -28290,11 +28726,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2570, __pyx_L1_error)
+    __PYX_ERR(0, 2666, __pyx_L1_error)
   }
   fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":2571
+  /* "pywrapfst.pyx":2667
  *                                         delta))
  *     fst.RmEpsilon(self._mfst.get(), deref(opts))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28303,11 +28739,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2571, __pyx_L1_error)
+    __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, 2571, __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)
 
-  /* "pywrapfst.pyx":2556
+  /* "pywrapfst.pyx":2652
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28318,12 +28754,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2573
+/* "pywrapfst.pyx":2669
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28332,13 +28768,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__rmepsilon(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_50rmepsilon[] = "\n    rmepsilon(self, queue_type=\"auto\", connect=True, weight=None,\n              nstate=NO_STATE_ID, delta=1e-6):\n\n    Removes epsilon transitions.\n\n    This operation destructively removes epsilon transitions, i.e., those where\n    both input and output labels are epsilon) from an FST.\n\n    Args:\n      queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n          \"lifo\", \"shortest\", \"state\", \"top\".\n      connect: Should output be trimmed?\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n      nstate: State number threshold.\n      delta: Comparison/quantization delta.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_50rmepsilon[] = "\n    rmepsilon(self, queue_type=\"auto\", connect=True, weight=None,\n              nstate=NO_STATE_ID, delta=1e-6):\n\n    Removes epsilon transitions.\n\n    This operation destructively removes epsilon transitions, i.e., those where\n    both input and output labels are epsilon) from an FST.\n\n    Args:\n      queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n          \"lifo\", \"shortest\", \"state\", \"top\".\n      connect: Should output be trimmed?\n      weight: A Weight or weight string indicating the desired weight threshold\n          below which paths are pruned; if omitted, no paths are pruned.\n      nstate: State number threshold.\n      delta: Comparison/quantization delta.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_connect;
   PyObject *__pyx_v_weight = 0;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
+  int64 __pyx_v_nstate;
   float __pyx_v_delta;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -28348,7 +28784,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
     PyObject* values[5] = {0,0,0,0,0};
     values[0] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":2576
+    /* "pywrapfst.pyx":2672
  *                 queue_type=b"auto",
  *                 bool connect=True,
  *                 weight=None,             # <<<<<<<<<<<<<<
@@ -28406,7 +28842,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2573, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2669, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28426,10 +28862,10 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2575, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2671, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2575
+      /* "pywrapfst.pyx":2671
  *   def rmepsilon(self,
  *                 queue_type=b"auto",
  *                 bool connect=True,             # <<<<<<<<<<<<<<
@@ -28440,27 +28876,27 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2577, __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, 2673, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__19;
+      __pyx_v_nstate = __pyx_k__20;
     }
     if (values[4]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2578, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2674, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__20;
+      __pyx_v_delta = __pyx_k__21;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2573, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2669, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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);
+  __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":2573
+  /* "pywrapfst.pyx":2669
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28473,13 +28909,13 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon(PyObject *__pyx_v
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nstate, float __pyx_v_delta) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon __pyx_t_1;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2600
+  /* "pywrapfst.pyx":2696
  *       self.
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -28488,7 +28924,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_rmepsilon");
-    __PYX_ERR(0, 2600, __pyx_L1_error)
+    __PYX_ERR(0, 2696, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 5;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
@@ -28496,9 +28932,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   __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, 2600, __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, 2696, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2601
+  /* "pywrapfst.pyx":2697
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -28510,7 +28946,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2573
+  /* "pywrapfst.pyx":2669
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -28520,7 +28956,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -28528,7 +28964,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2603
+/* "pywrapfst.pyx":2699
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -28536,7 +28972,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_50rmepsilon(struct __pyx_obj_
  *       raise FstIndexError("State index out of range")
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final *__pyx_optional_args) {
+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;
   __Pyx_RefNannyDeclarations
@@ -28552,7 +28988,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
   }
 
-  /* "pywrapfst.pyx":2604
+  /* "pywrapfst.pyx":2700
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -28561,19 +28997,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2604, __pyx_L1_error)
+    __PYX_ERR(0, 2700, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2605
+    /* "pywrapfst.pyx":2701
  *   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)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2605, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2701, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28587,14 +29023,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __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, 2605, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2701, __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, 2605, __pyx_L1_error)
+    __PYX_ERR(0, 2701, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2604
+    /* "pywrapfst.pyx":2700
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -28603,7 +29039,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2606
+  /* "pywrapfst.pyx":2702
  *     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(),             # <<<<<<<<<<<<<<
@@ -28612,20 +29048,20 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2606, __pyx_L1_error)
+    __PYX_ERR(0, 2702, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2607
+  /* "pywrapfst.pyx":2703
  *       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):
  *       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, 2606, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":2608
+  /* "pywrapfst.pyx":2704
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -28634,19 +29070,19 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2608, __pyx_L1_error)
+    __PYX_ERR(0, 2704, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v_wc) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2609
+    /* "pywrapfst.pyx":2705
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):
  *       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, 2609, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2705, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28660,14 +29096,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
     }
     __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, 2609, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2705, __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, 2609, __pyx_L1_error)
+    __PYX_ERR(0, 2705, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2608
+    /* "pywrapfst.pyx":2704
  *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
  *                                                       weight)
  *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
@@ -28676,7 +29112,7 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":2610
+  /* "pywrapfst.pyx":2706
  *     if not self._mfst.get().SetFinal(state, wc):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28685,11 +29121,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2610, __pyx_L1_error)
+    __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, 2610, __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)
 
-  /* "pywrapfst.pyx":2603
+  /* "pywrapfst.pyx":2699
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -28703,12 +29139,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2612
+/* "pywrapfst.pyx":2708
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -28717,10 +29153,10 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_final(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_52set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_52set_final[] = "\n    set_final(self, state, weight)\n\n    Sets the final weight for a state.\n\n    Args:\n      state: The integer index of a state.\n      weight: A Weight or weight string indicating the desired final weight; if\n          omitted, it is set to semiring One.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n      FstOpError: Incompatible or invalid weight.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -28753,7 +29189,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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, 2612, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2708, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28764,31 +29200,31 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2612, __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, 2708, __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, 2612, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2708, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_52set_final(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_weight);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_52set_final(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_weight);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final __pyx_t_1;
+  struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final __pyx_t_1;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2630
+  /* "pywrapfst.pyx":2726
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
@@ -28797,13 +29233,13 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_final");
-    __PYX_ERR(0, 2630, __pyx_L1_error)
+    __PYX_ERR(0, 2726, __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, 2630, __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, 2726, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2631
+  /* "pywrapfst.pyx":2727
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -28815,7 +29251,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2612
+  /* "pywrapfst.pyx":2708
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -28825,7 +29261,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -28833,7 +29269,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2633
+/* "pywrapfst.pyx":2729
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -28841,13 +29277,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_52set_final(struct __pyx_obj_
  *       self._mfst.get().SetInputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__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__SymbolTable *__pyx_v_syms) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
+  fst::SymbolTable const *__pyx_t_3;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2634
+  /* "pywrapfst.pyx":2730
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -28858,29 +29295,29 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2635
+    /* "pywrapfst.pyx":2731
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mfst.get().SetInputSymbols(syms._table)
+ *     self._mfst.get().SetInputSymbols(syms._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, 2635, __pyx_L1_error)
+      __PYX_ERR(0, 2731, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2636
+    /* "pywrapfst.pyx":2732
  *     if syms is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetInputSymbols(syms._table)
- *     self._check_mutating_imethod()
+ *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2634
+    /* "pywrapfst.pyx":2730
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -28889,37 +29326,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
   }
 
-  /* "pywrapfst.pyx":2637
+  /* "pywrapfst.pyx":2733
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
- *     self._mfst.get().SetInputSymbols(syms._table)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
+ *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
+ *   def set_input_symbols(self, _SymbolTable syms):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2637, __pyx_L1_error)
+    __PYX_ERR(0, 2733, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2637, __pyx_L1_error)
-  }
-  __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_v_syms->_table);
-
-  /* "pywrapfst.pyx":2638
- *       return
- *     self._mfst.get().SetInputSymbols(syms._table)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def set_input_symbols(self, _SymbolTable syms):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2638, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 2733, __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, 2638, __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_v_self->_mfst.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2633
+  /* "pywrapfst.pyx":2729
  *     return self
  * 
  *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -28930,13 +29355,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2640
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2735
+ *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
@@ -28944,14 +29369,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_input_symbols(struct __pyx_obj
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_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_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) {
   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, 2640, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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_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));
 
   /* function exit code */
   goto __pyx_L0;
@@ -28962,12 +29387,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2654
+  /* "pywrapfst.pyx":2749
  *       self.
  *     """
  *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
@@ -28976,11 +29401,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 2654, __pyx_L1_error)
+    __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_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2654, __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)
 
-  /* "pywrapfst.pyx":2655
+  /* "pywrapfst.pyx":2750
  *     """
  *     self._set_input_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -28992,8 +29417,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2640
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2735
+ *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
  * 
  *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
@@ -29002,7 +29427,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_input_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -29010,7 +29435,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2657
+/* "pywrapfst.pyx":2752
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -29018,13 +29443,14 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_54set_input_symbols(struct __
  *       self._mfst.get().SetOutputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__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__SymbolTable *__pyx_v_syms) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
+  fst::SymbolTable const *__pyx_t_3;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2658
+  /* "pywrapfst.pyx":2753
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -29035,29 +29461,29 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2659
+    /* "pywrapfst.pyx":2754
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)
+ *     self._mfst.get().SetOutputSymbols(syms._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, 2659, __pyx_L1_error)
+      __PYX_ERR(0, 2754, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2660
+    /* "pywrapfst.pyx":2755
  *     if syms is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetOutputSymbols(syms._table)
- *     self._check_mutating_imethod()
+ *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2658
+    /* "pywrapfst.pyx":2753
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
  *     if syms is None:             # <<<<<<<<<<<<<<
@@ -29066,37 +29492,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":2661
+  /* "pywrapfst.pyx":2756
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
+ *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
+ *   def set_output_symbols(self, _SymbolTable syms):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2661, __pyx_L1_error)
+    __PYX_ERR(0, 2756, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 2661, __pyx_L1_error)
-  }
-  __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_v_syms->_table);
-
-  /* "pywrapfst.pyx":2662
- *       return
- *     self._mfst.get().SetOutputSymbols(syms._table)
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
- * 
- *   def set_output_symbols(self, _SymbolTable syms):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2662, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+    __PYX_ERR(0, 2756, __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, 2662, __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_v_self->_mfst.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2657
+  /* "pywrapfst.pyx":2752
  *     return self
  * 
  *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
@@ -29107,13 +29521,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2664
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2758
+ *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
@@ -29121,14 +29535,14 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_output_symbols(struct __pyx_ob
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_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_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) {
   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, 2664, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_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_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));
 
   /* function exit code */
   goto __pyx_L0;
@@ -29139,12 +29553,12 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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__SymbolTable *__pyx_v_syms) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2678
+  /* "pywrapfst.pyx":2772
  *       self.
  *     """
  *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
@@ -29153,11 +29567,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 2678, __pyx_L1_error)
+    __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_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2678, __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)
 
-  /* "pywrapfst.pyx":2679
+  /* "pywrapfst.pyx":2773
  *     """
  *     self._set_output_symbols(syms)
  *     return self             # <<<<<<<<<<<<<<
@@ -29169,8 +29583,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2664
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2758
+ *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
  * 
  *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
  *     """
@@ -29179,7 +29593,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_output_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -29187,7 +29601,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2681
+/* "pywrapfst.pyx":2775
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29195,11 +29609,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_56set_output_symbols(struct _
  * 
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+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
   __Pyx_RefNannySetupContext("_set_properties", 0);
 
-  /* "pywrapfst.pyx":2682
+  /* "pywrapfst.pyx":2776
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):
  *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
@@ -29208,11 +29622,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2682, __pyx_L1_error)
+    __PYX_ERR(0, 2776, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2681
+  /* "pywrapfst.pyx":2775
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29223,12 +29637,12 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_WriteUnraisable("pywrapfst._MutableFst._set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2684
+/* "pywrapfst.pyx":2778
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29237,11 +29651,11 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_properties(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_58set_properties[] = "\n    set_properties(self, props, mask)\n\n    Sets the properties bits.\n\n    Args:\n      props: The properties to be set.\n      mask: A mask to be applied to the `props` argument before setting the\n          FST's properties.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint64 __pyx_v_props;
-  __pyx_t_10basictypes_uint64 __pyx_v_mask;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_58set_properties[] = "\n    set_properties(self, props, mask)\n\n    Sets the properties bits.\n\n    Args:\n      props: The properties to be set.\n      mask: A mask to be applied to the `props` argument before setting the\n          FST's properties.\n\n    Returns:\n      self.\n    ";
+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;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_properties (wrapper)", 0);
@@ -29268,11 +29682,11 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__
         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, 2684, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2778, __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, 2684, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2778, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -29280,30 +29694,30 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_59set_properties(PyObject *__
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2684, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2684, __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, 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)
   }
   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, 2684, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2778, __pyx_L3_error)
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_58set_properties(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_props, __pyx_v_mask);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_58set_properties(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_props, __pyx_v_mask);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_uint64 __pyx_v_props, __pyx_t_10basictypes_uint64 __pyx_v_mask) {
+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
   __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2698
+  /* "pywrapfst.pyx":2792
  *       self.
  *     """
  *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
@@ -29312,11 +29726,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_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, 2698, __pyx_L1_error)
+    __PYX_ERR(0, 2792, __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);
+  ((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":2699
+  /* "pywrapfst.pyx":2793
  *     """
  *     self._set_properties(props, mask)
  *     return self             # <<<<<<<<<<<<<<
@@ -29328,7 +29742,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2684
+  /* "pywrapfst.pyx":2778
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29338,7 +29752,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -29346,7 +29760,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2701
+/* "pywrapfst.pyx":2795
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29354,7 +29768,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_58set_properties(struct __pyx
  *       raise FstIndexError("State index out of range")
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -29362,28 +29776,28 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2702
+  /* "pywrapfst.pyx":2796
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     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, 2702, __pyx_L1_error)
+    __PYX_ERR(0, 2796, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2703
+    /* "pywrapfst.pyx":2797
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def set_start(self, int64 state):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2703, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2797, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29397,36 +29811,23 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
     }
     __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, 2703, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2797, __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, 2703, __pyx_L1_error)
+    __PYX_ERR(0, 2797, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2702
+    /* "pywrapfst.pyx":2796
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     self._check_mutating_imethod()
- */
-  }
-
-  /* "pywrapfst.pyx":2704
- *     if not self._mfst.get().SetStart(state):
- *       raise FstIndexError("State index out of range")
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def set_start(self, int64 state):
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2704, __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, 2704, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2701
+  /* "pywrapfst.pyx":2795
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29440,13 +29841,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst._set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2706
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2799
+ *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -29454,35 +29855,35 @@ static void __pyx_f_9pywrapfst_11_MutableFst__set_start(struct __pyx_obj_9pywrap
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_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_11_MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
+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;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2706, __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, 2799, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_60set_start(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_state));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_60set_start(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((int64)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_state) {
+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
   __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2721
+  /* "pywrapfst.pyx":2814
  *       FstIndexError: State index out of range.
  *     """
  *     self._set_start(state)             # <<<<<<<<<<<<<<
@@ -29491,24 +29892,24 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_start");
-    __PYX_ERR(0, 2721, __pyx_L1_error)
+    __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, 2721, __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)
 
-  /* "pywrapfst.pyx":2722
+  /* "pywrapfst.pyx":2815
  *     """
  *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _topsort(self) except *:
+ *   cdef void _topsort(self):
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2706
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2799
+ *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -29517,7 +29918,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.set_start", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -29525,15 +29926,15 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_60set_start(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2724
+/* "pywrapfst.pyx":2817
  *     return self
  * 
- *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
+ *   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()):
  */
 
-static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -29541,30 +29942,30 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2726
- *   cdef void _topsort(self) except *:
+  /* "pywrapfst.pyx":2819
+ *   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()):             # <<<<<<<<<<<<<<
  *       logging.warning("Cannot topsort cyclic FST")
- *     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, 2726, __pyx_L1_error)
+    __PYX_ERR(0, 2819, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2727
+    /* "pywrapfst.pyx":2820
  *     # 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")             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
  * 
+ *   def topsort(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2727, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2820, __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, 2727, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -29579,37 +29980,24 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
     }
     __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, 2727, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2820, __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":2726
- *   cdef void _topsort(self) except *:
+    /* "pywrapfst.pyx":2819
+ *   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()):             # <<<<<<<<<<<<<<
  *       logging.warning("Cannot topsort cyclic FST")
- *     self._check_mutating_imethod()
- */
-  }
-
-  /* "pywrapfst.pyx":2728
- *     if not fst.TopSort(self._mfst.get()):
- *       logging.warning("Cannot topsort cyclic FST")
- *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
- *   def topsort(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, 2728, __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, 2728, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2724
+  /* "pywrapfst.pyx":2817
  *     return self
  * 
- *   cdef void _topsort(self) except *:             # <<<<<<<<<<<<<<
+ *   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()):
  */
@@ -29620,13 +30008,13 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._MutableFst._topsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.MutableFst._topsort", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2730
- *     self._check_mutating_imethod()
+/* "pywrapfst.pyx":2822
+ *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
  *     """
@@ -29634,25 +30022,25 @@ static void __pyx_f_9pywrapfst_11_MutableFst__topsort(struct __pyx_obj_9pywrapfs
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_62topsort[] = "\n    topsort(self)\n\n    Sorts transitions by state IDs.\n\n    This operation destructively topologically sorts the FST, if it is acyclic;\n    otherwise it remains unchanged. Once sorted, all transitions are from lower\n    state IDs to higher state IDs\n\n    Returns:\n       self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_62topsort[] = "\n    topsort(self)\n\n    Sorts transitions by state IDs.\n\n    This operation destructively topologically sorts the FST, if it is acyclic;\n    otherwise it remains unchanged. Once sorted, all transitions are from lower\n    state IDs to higher state IDs\n\n    Returns:\n       self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_63topsort(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_62topsort(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_62topsort(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2743
+  /* "pywrapfst.pyx":2835
  *        self.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -29661,11 +30049,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_topsort");
-    __PYX_ERR(0, 2743, __pyx_L1_error)
+    __PYX_ERR(0, 2835, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst__MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2743, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2744
+  /* "pywrapfst.pyx":2836
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
@@ -29677,8 +30065,8 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2730
- *     self._check_mutating_imethod()
+  /* "pywrapfst.pyx":2822
+ *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
  *     """
@@ -29687,7 +30075,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._MutableFst.topsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.topsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -29695,7 +30083,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2746
+/* "pywrapfst.pyx":2838
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -29704,9 +30092,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_62topsort(struct __pyx_obj_9p
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_11_MutableFst_64union[] = "\n    union(self, *fsts2)\n\n    Computes the union (sum) of two or more FSTs.\n\n    This operation computes the union of two or more FSTs. If A transduces\n    string x to y with weight a and B transduces string w to v with weight b,\n    then their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      *fsts2: One or more input FSTs.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_64union[] = "\n    union(self, *fsts2)\n\n    Computes the union (sum) of two or more FSTs.\n\n    This operation computes the union of two or more FSTs. If A transduces\n    string x to y with weight a and B transduces string w to v with weight b,\n    then their union transduces x to y with weight a and w to v with weight b.\n\n    Args:\n      *fsts2: One or more input FSTs.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_65union(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_fsts2 = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -29714,7 +30102,7 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_sel
   if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "union", 0))) return NULL;
   __Pyx_INCREF(__pyx_args);
   __pyx_v_fsts2 = __pyx_args;
-  __pyx_r = __pyx_pf_9pywrapfst_11_MutableFst_64union(((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_v_self), __pyx_v_fsts2);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_64union(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_fsts2);
 
   /* function exit code */
   __Pyx_XDECREF(__pyx_v_fsts2);
@@ -29722,9 +30110,9 @@ static PyObject *__pyx_pw_9pywrapfst_11_MutableFst_65union(PyObject *__pyx_v_sel
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2) {
   std::vector<__pyx_t_9pywrapfst_const_FstClass_ptr>  __pyx_v__fsts2;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_fst2 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2 = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -29732,9 +30120,9 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2764
+  /* "pywrapfst.pyx":2856
  *     cdef vector[const_FstClass_ptr] _fsts2
- *     cdef _Fst fst2
+ *     cdef Fst fst2
  *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
  *       _fsts2.push_back(fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
@@ -29743,17 +30131,17 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   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, 2764, __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, 2856, __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, 2764, __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, 2856, __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, 2764, __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, 2856, __pyx_L1_error)
+    __Pyx_XDECREF_SET(__pyx_v_fst2, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2765
- *     cdef _Fst fst2
+    /* "pywrapfst.pyx":2857
+ *     cdef Fst fst2
  *     for fst2 in fsts2:
  *       _fsts2.push_back(fst2._fst.get())             # <<<<<<<<<<<<<<
  *     fst.Union(self._mfst.get(), _fsts2)
@@ -29761,18 +30149,18 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
  */
     if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2765, __pyx_L1_error)
+      __PYX_ERR(0, 2857, __pyx_L1_error)
     }
     try {
       __pyx_v__fsts2.push_back(__pyx_v_fst2->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2765, __pyx_L1_error)
+      __PYX_ERR(0, 2857, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2764
+    /* "pywrapfst.pyx":2856
  *     cdef vector[const_FstClass_ptr] _fsts2
- *     cdef _Fst fst2
+ *     cdef Fst fst2
  *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
  *       _fsts2.push_back(fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
@@ -29780,7 +30168,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2766
+  /* "pywrapfst.pyx":2858
  *     for fst2 in fsts2:
  *       _fsts2.push_back(fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)             # <<<<<<<<<<<<<<
@@ -29789,11 +30177,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(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, 2766, __pyx_L1_error)
+    __PYX_ERR(0, 2858, __pyx_L1_error)
   }
   fst::script::Union(__pyx_v_self->_mfst.get(), __pyx_v__fsts2);
 
-  /* "pywrapfst.pyx":2767
+  /* "pywrapfst.pyx":2859
  *       _fsts2.push_back(fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -29802,11 +30190,11 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(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, 2767, __pyx_L1_error)
+    __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, 2767, __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)
 
-  /* "pywrapfst.pyx":2768
+  /* "pywrapfst.pyx":2860
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()
  *     return self             # <<<<<<<<<<<<<<
@@ -29818,7 +30206,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2746
+  /* "pywrapfst.pyx":2838
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -29830,7 +30218,7 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._MutableFst.union", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.MutableFst.union", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XDECREF((PyObject *)__pyx_v_fst2);
@@ -29839,17 +30227,231 @@ static PyObject *__pyx_pf_9pywrapfst_11_MutableFst_64union(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2793
+/* "pywrapfst.pyx":2876
+ *   """
+ * 
+ *   def __init__(self, arc_type=b"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_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);
+    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_arc_type);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      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)
+      }
+    } 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;
+      }
+    }
+    __pyx_v_arc_type = values[0];
+  }
+  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_L3_error:;
+  __Pyx_AddTraceback("pywrapfst.VectorFst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_9VectorFst___init__(((struct __pyx_obj_9pywrapfst_VectorFst *)__pyx_v_self), __pyx_v_arc_type);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+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;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  std::string __pyx_t_1;
+  int __pyx_t_2;
+  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("__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))
+ */
+  __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));
+
+  /* "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())
+ */
+  __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())
+ *     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_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_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = 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)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_6);
+        __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_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)
+
+    /* "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":2881
+ *     if tfst.get().Properties(fst.kError, True) == fst.kError:
+ *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+ *     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_v_self->__pyx_base.__pyx_base._fst.reset(__pyx_v_tfst.release());
+
+  /* "pywrapfst.pyx":2883
+ *     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, 2883, __pyx_L1_error)
+  }
+
+  /* "pywrapfst.pyx":2882
+ *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+ *     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_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
+ *   """
+ * 
+ *   def __init__(self, arc_type=b"standard"):             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.MutableFstClass] tfst
+ *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __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.VectorFst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":2902
  * 
  * 
- * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  */
 
-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_r = NULL;
+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_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -29857,24 +30459,24 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2794
+  /* "pywrapfst.pyx":2903
  * 
- * cdef _Fst _init_Fst(FstClass_ptr tfst):
+ * 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":2795
- * cdef _Fst _init_Fst(FstClass_ptr tfst):
+    /* "pywrapfst.pyx":2904
+ * 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)
  *   ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2795, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2904, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29888,49 +30490,49 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
     }
     __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, 2795, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2904, __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, 2795, __pyx_L1_error)
+    __PYX_ERR(0, 2904, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2794
+    /* "pywrapfst.pyx":2903
  * 
- * cdef _Fst _init_Fst(FstClass_ptr tfst):
+ * 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":2796
+  /* "pywrapfst.pyx":2905
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
- *   cdef _Fst ofst = _Fst.__new__(_Fst)             # <<<<<<<<<<<<<<
+ *   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, 2796, __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, 2905, __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":2797
+  /* "pywrapfst.pyx":2906
  *     raise FstOpError("Operation failed")
- *   cdef _Fst ofst = _Fst.__new__(_Fst)
+ *   cdef Fst ofst = Fst.__new__(Fst)
  *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
  *   return ofst
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2797, __pyx_L1_error)
+    __PYX_ERR(0, 2906, __pyx_L1_error)
   }
   __pyx_v_ofst->_fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2798
- *   cdef _Fst ofst = _Fst.__new__(_Fst)
+  /* "pywrapfst.pyx":2907
+ *   cdef Fst ofst = Fst.__new__(Fst)
  *   ofst._fst.reset(tfst)
  *   return ofst             # <<<<<<<<<<<<<<
  * 
@@ -29941,10 +30543,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2793
+  /* "pywrapfst.pyx":2902
  * 
  * 
- * cdef _Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  */
@@ -29963,17 +30565,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2801
+/* "pywrapfst.pyx":2910
  * 
  * 
- * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  */
 
-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_r = NULL;
+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_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -29981,24 +30583,24 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2802
+  /* "pywrapfst.pyx":2911
  * 
- * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
+ * 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":2803
- * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
+    /* "pywrapfst.pyx":2912
+ * 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)
  *   ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2803, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2912, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30012,48 +30614,48 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
     }
     __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, 2803, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2912, __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, 2803, __pyx_L1_error)
+    __PYX_ERR(0, 2912, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2802
+    /* "pywrapfst.pyx":2911
  * 
- * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
+ * 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":2804
+  /* "pywrapfst.pyx":2913
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
- *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)             # <<<<<<<<<<<<<<
+ *   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, 2804, __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, 2913, __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":2805
+  /* "pywrapfst.pyx":2914
  *     raise FstOpError("Operation failed")
- *   cdef _MutableFst ofst = _MutableFst.__new__(_MutableFst)
+ *   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)
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2805, __pyx_L1_error)
+    __PYX_ERR(0, 2914, __pyx_L1_error)
   }
   __pyx_v_ofst->__pyx_base._fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2807
+  /* "pywrapfst.pyx":2916
  *   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)             # <<<<<<<<<<<<<<
@@ -30062,15 +30664,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
  */
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2807, __pyx_L1_error)
+    __PYX_ERR(0, 2916, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2807, __pyx_L1_error)
+    __PYX_ERR(0, 2916, __pyx_L1_error)
   }
   __pyx_v_ofst->_mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v_ofst->__pyx_base._fst);
 
-  /* "pywrapfst.pyx":2808
+  /* "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             # <<<<<<<<<<<<<<
@@ -30082,10 +30684,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   __pyx_r = __pyx_v_ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2801
+  /* "pywrapfst.pyx":2910
  * 
  * 
- * cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
  */
@@ -30104,24 +30706,24 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__init_Mutable
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2811
+/* "pywrapfst.pyx":2920
  * 
  * 
- * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  */
 
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9pywrapfst_FstClass_ptr __pyx_v_tfst) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9pywrapfst_FstClass_ptr __pyx_v_tfst) {
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("_init_XFst", 0);
 
-  /* "pywrapfst.pyx":2812
+  /* "pywrapfst.pyx":2921
  * 
- * cdef _Fst _init_XFst(FstClass_ptr tfst):
+ * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
@@ -30129,30 +30731,30 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kMutable, 1) == fst::kMutable) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2813
- * cdef _Fst _init_XFst(FstClass_ptr tfst):
+    /* "pywrapfst.pyx":2922
+ * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
  *   else:
  *     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, 2813, __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, 2922, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
+    __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2812
+    /* "pywrapfst.pyx":2921
  * 
- * cdef _Fst _init_XFst(FstClass_ptr tfst):
+ * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  */
   }
 
-  /* "pywrapfst.pyx":2815
+  /* "pywrapfst.pyx":2924
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -30161,17 +30763,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
  */
   /*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, 2815, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_2);
-    __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
+    __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":2811
+  /* "pywrapfst.pyx":2920
  * 
  * 
- * cdef _Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
+ * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  */
@@ -30187,157 +30789,18 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2818
+/* "pywrapfst.pyx":2927
  * 
  * 
- * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- */
-
-static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst__create_Fst(struct __pyx_opt_args_9pywrapfst__create_Fst *__pyx_optional_args) {
-  PyObject *__pyx_v_arc_type = ((PyObject *)__pyx_n_b_standard);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  std::string __pyx_t_1;
-  int __pyx_t_2;
-  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("_create_Fst", 0);
-  if (__pyx_optional_args) {
-    if (__pyx_optional_args->__pyx_n > 0) {
-      __pyx_v_arc_type = __pyx_optional_args->arc_type;
-    }
-  }
-
-  /* "pywrapfst.pyx":2820
- * cdef _MutableFst _create_Fst(arc_type=b"standard"):
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
- *   if tfst.get() == NULL:
- *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2820, __pyx_L1_error)
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
-
-  /* "pywrapfst.pyx":2821
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *   return _init_MutableFst(tfst.release())
- */
-  __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
-  if (unlikely(__pyx_t_2)) {
-
-    /* "pywrapfst.pyx":2822
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *   if tfst.get() == NULL:
- *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
- * 
- */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2822, __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, 2822, __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, 2822, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = 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)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
-        __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, 2822, __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, 2822, __pyx_L1_error)
-
-    /* "pywrapfst.pyx":2821
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *   return _init_MutableFst(tfst.release())
- */
-  }
-
-  /* "pywrapfst.pyx":2823
- *   if tfst.get() == NULL:
- *     raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *   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, 2823, __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":2818
- * 
- * 
- * cdef _MutableFst _create_Fst(arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __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._create_Fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF((PyObject *)__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":2826
- * 
- * 
- * cpdef _Fst _read(source):             # <<<<<<<<<<<<<<
+ * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(source)))
  */
 
-static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__pyx_v_source, CYTHON_UNUSED int __pyx_skip_dispatch) {
+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;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -30346,19 +30809,19 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
-  __Pyx_RefNannySetupContext("_read", 0);
+  __Pyx_RefNannySetupContext("_read_Fst", 0);
 
-  /* "pywrapfst.pyx":2828
- * cpdef _Fst _read(source):
+  /* "pywrapfst.pyx":2929
+ * 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))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2828, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":2829
+  /* "pywrapfst.pyx":2930
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(source)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30368,16 +30831,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2830
+    /* "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())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2830, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2931, __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, 2830, __pyx_L1_error)
+    __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))) {
@@ -30391,7 +30854,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
     }
     __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, 2830, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2931, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -30407,14 +30870,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
     __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, 2830, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2931, __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, 2830, __pyx_L1_error)
+    __PYX_ERR(0, 2931, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2829
+    /* "pywrapfst.pyx":2930
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(source)))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30423,7 +30886,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
  */
   }
 
-  /* "pywrapfst.pyx":2831
+  /* "pywrapfst.pyx":2932
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed: {!r}".format(source))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -30431,16 +30894,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
  * 
  */
   __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, 2831, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2826
+  /* "pywrapfst.pyx":2927
  * 
  * 
- * cpdef _Fst _read(source):             # <<<<<<<<<<<<<<
+ * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.Read(tostring(source)))
  */
@@ -30452,7 +30915,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_AddTraceback("pywrapfst._read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._read_Fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -30461,25 +30924,25 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read(PyObject *__py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_17_read(PyObject *__pyx_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pw_9pywrapfst_17_read_Fst(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_17_read_Fst(PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_read (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_16_read(__pyx_self, ((PyObject *)__pyx_v_source));
+  __Pyx_RefNannySetupContext("_read_Fst (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_16_read_Fst(__pyx_self, ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("_read", 0);
+  __Pyx_RefNannySetupContext("_read_Fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2826, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30488,7 +30951,7 @@ static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self,
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._read", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst._read_Fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -30496,19 +30959,19 @@ static PyObject *__pyx_pf_9pywrapfst_16_read(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2834
+/* "pywrapfst.pyx":2935
  * 
  * 
- * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
+ * cpdef Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
  *   cdef stringstream sstrm
  *   sstrm << tostring(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) {
+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;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -30517,17 +30980,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   PyObject *__pyx_t_5 = NULL;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
 
-  /* "pywrapfst.pyx":2836
- * cpdef _Fst _read_Fst_from_string(state):
+  /* "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>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2836, __pyx_L1_error)
+  __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));
 
-  /* "pywrapfst.pyx":2838
+  /* "pywrapfst.pyx":2939
  *   sstrm << tostring(state)
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
@@ -30536,7 +30999,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":2839
+  /* "pywrapfst.pyx":2940
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30546,14 +31009,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2840
+    /* "pywrapfst.pyx":2941
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
  *   return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2840, __pyx_L1_error)
+    __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))) {
@@ -30567,14 +31030,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
     }
     __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, 2840, __pyx_L1_error)
+    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_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2840, __pyx_L1_error)
+    __PYX_ERR(0, 2941, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2839
+    /* "pywrapfst.pyx":2940
  *   cdef unique_ptr[fst.FstClass] tfst
  *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -30583,7 +31046,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  */
   }
 
-  /* "pywrapfst.pyx":2841
+  /* "pywrapfst.pyx":2942
  *   if tfst.get() == NULL:
  *     raise FstIOError("Read failed")
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -30591,16 +31054,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__read_Fst_from_strin
  * 
  */
   __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, 2841, __pyx_L1_error)
+  __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_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2834
+  /* "pywrapfst.pyx":2935
  * 
  * 
- * cpdef _Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
+ * cpdef Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
  *   cdef stringstream sstrm
  *   sstrm << tostring(state)
  */
@@ -30637,7 +31100,7 @@ static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObj
   PyObject *__pyx_t_1 = NULL;
   __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, 2834, __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, 2935, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30654,247 +31117,7 @@ static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2861
- *    """
- * 
- *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     return _create_Fst(arc_type)
- * 
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_1__new__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_1__new__ = {"__new__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_3Fst_1__new__, METH_VARARGS|METH_KEYWORDS, 0};
-static PyObject *__pyx_pw_9pywrapfst_3Fst_1__new__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  CYTHON_UNUSED PyObject *__pyx_v_cls = 0;
-  PyObject *__pyx_v_arc_type = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__new__ (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_cls,&__pyx_n_s_arc_type,0};
-    PyObject* values[2] = {0,0};
-    values[1] = ((PyObject *)((PyObject*)__pyx_n_b_standard));
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        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 (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_cls)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        CYTHON_FALLTHROUGH;
-        case  1:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_arc_type);
-          if (value) { values[1] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__new__") < 0)) __PYX_ERR(0, 2861, __pyx_L3_error)
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        CYTHON_FALLTHROUGH;
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-    }
-    __pyx_v_cls = values[0];
-    __pyx_v_arc_type = values[1];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__new__", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2861, __pyx_L3_error)
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.Fst.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst___new__(__pyx_self, __pyx_v_cls, __pyx_v_arc_type);
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_3Fst___new__(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_cls, PyObject *__pyx_v_arc_type) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  struct __pyx_opt_args_9pywrapfst__create_Fst __pyx_t_2;
-  __Pyx_RefNannySetupContext("__new__", 0);
-
-  /* "pywrapfst.pyx":2862
- * 
- *    def __new__(cls, arc_type=b"standard"):
- *     return _create_Fst(arc_type)             # <<<<<<<<<<<<<<
- * 
- *    @staticmethod
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2.__pyx_n = 1;
-  __pyx_t_2.arc_type = __pyx_v_arc_type;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__create_Fst(&__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2862, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":2861
- *    """
- * 
- *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     return _create_Fst(arc_type)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.Fst.__new__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":2865
- * 
- *    @staticmethod
- *    def read(source):             # <<<<<<<<<<<<<<
- *      """
- *      read(source)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_2read[] = "\n     read(source)\n\n     Reads an FST from a file.\n\n     Args:\n       source: The string location of the input file.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n     ";
-static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_3read = {"read", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_3read, METH_O, __pyx_doc_9pywrapfst_3Fst_2read};
-static PyObject *__pyx_pw_9pywrapfst_3Fst_3read(PyObject *__pyx_self, PyObject *__pyx_v_source) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("read (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_2read(__pyx_self, ((PyObject *)__pyx_v_source));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_3Fst_2read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("read", 0);
-
-  /* "pywrapfst.pyx":2880
- *        FstIOError: Read failed.
- *      """
- *      return _read(source)             # <<<<<<<<<<<<<<
- * 
- *    @staticmethod
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2880, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":2865
- * 
- *    @staticmethod
- *    def read(source):             # <<<<<<<<<<<<<<
- *      """
- *      read(source)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.Fst.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":2883
- * 
- *    @staticmethod
- *    def read_from_string(state):             # <<<<<<<<<<<<<<
- *      """
- *      read_from_string(state)
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_4read_from_string[] = "\n     read_from_string(state)\n\n     Reads an FST from a serialized string.\n\n     Args:\n       state: A string containing the serialized FST.\n\n     Returns:\n       An FST object.\n\n     Raises:\n       FstIOError: Read failed.\n     ";
-static PyMethodDef __pyx_mdef_9pywrapfst_3Fst_5read_from_string = {"read_from_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_5read_from_string, METH_O, __pyx_doc_9pywrapfst_3Fst_4read_from_string};
-static PyObject *__pyx_pw_9pywrapfst_3Fst_5read_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("read_from_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_4read_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_3Fst_4read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("read_from_string", 0);
-
-  /* "pywrapfst.pyx":2898
- *        FstIOError: Read failed.
- *      """
- *      return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __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, 2898, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":2883
- * 
- *    @staticmethod
- *    def read_from_string(state):             # <<<<<<<<<<<<<<
- *      """
- *      read_from_string(state)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.Fst.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":3011
+/* "pywrapfst.pyx":3055
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -30924,7 +31147,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3012
+  /* "pywrapfst.pyx":3056
  * 
  *   def __repr__(self):
  *     return "<Arc at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
@@ -30932,9 +31155,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
  *   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, 3012, __pyx_L1_error)
+  __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, 3012, __pyx_L1_error)
+  __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))) {
@@ -30949,14 +31172,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   __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, 3012, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3056, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3011
+  /* "pywrapfst.pyx":3055
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -30978,7 +31201,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3014
+/* "pywrapfst.pyx":3058
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -30989,10 +31212,10 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_int64 __pyx_v_ilabel;
-  __pyx_t_10basictypes_int64 __pyx_v_olabel;
+  int64 __pyx_v_ilabel;
+  int64 __pyx_v_olabel;
   PyObject *__pyx_v_weight = 0;
-  __pyx_t_10basictypes_int64 __pyx_v_nextstate;
+  int64 __pyx_v_nextstate;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -31023,23 +31246,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, 3014, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3058, __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, 3014, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3058, __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, 3014, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3058, __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, 3014, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3058, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -31049,14 +31272,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3014, __pyx_L3_error)
-    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3014, __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, 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_weight = values[2];
-    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3014, __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, 3058, __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, 3014, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3058, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -31069,24 +31292,24 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_ilabel, __pyx_t_10basictypes_int64 __pyx_v_olabel, PyObject *__pyx_v_weight, __pyx_t_10basictypes_int64 __pyx_v_nextstate) {
+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;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3015
+  /* "pywrapfst.pyx":3059
  * 
  *   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))
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3015, __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, 3059, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3016
+  /* "pywrapfst.pyx":3060
  *   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))             # <<<<<<<<<<<<<<
@@ -31095,11 +31318,11 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3016, __pyx_L1_error)
+    __PYX_ERR(0, 3060, __pyx_L1_error)
   }
   __pyx_v_self->_arc.reset(new fst::script::ArcClass(__pyx_v_ilabel, __pyx_v_olabel, __pyx_v_wc, __pyx_v_nextstate));
 
-  /* "pywrapfst.pyx":3014
+  /* "pywrapfst.pyx":3058
  *     return "<Arc at 0x{:x}>".format(id(self))
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
@@ -31118,7 +31341,7 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3018
+/* "pywrapfst.pyx":3062
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -31145,7 +31368,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, 3018, __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, 3062, __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));
@@ -31162,10 +31385,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, 3018, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3062, __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, 3018, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3062, __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;
@@ -31184,7 +31407,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":3019
+  /* "pywrapfst.pyx":3063
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -31192,15 +31415,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, 3019, __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, 3063, __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, 3019, __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, 3063, __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, 3019, __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, 3063, __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, 3019, __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, 3063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3019, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3063, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -31214,14 +31437,14 @@ 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, 3019, __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, 3063, __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":3018
+  /* "pywrapfst.pyx":3062
  *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
@@ -31263,7 +31486,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   PyObject *__pyx_t_1 = NULL;
   __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, 3018, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31280,7 +31503,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3023
+/* "pywrapfst.pyx":3067
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31307,7 +31530,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3024
+  /* "pywrapfst.pyx":3068
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -31317,15 +31540,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, 3024, __pyx_L1_error)
+    __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, 3024, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3023
+  /* "pywrapfst.pyx":3067
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31344,7 +31567,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3026
+/* "pywrapfst.pyx":3070
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31355,12 +31578,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
 /* Python wrapper */
 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) {
-  __pyx_t_10basictypes_int64 __pyx_v_value;
+  int64 __pyx_v_value;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3026, __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, 3070, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31368,19 +31591,19 @@ static int __pyx_pw_9pywrapfst_3Arc_6ilabel_3__set__(PyObject *__pyx_v_self, PyO
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_value));
+  __pyx_r = __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((int64)__pyx_v_value));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value) {
+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
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3027
+  /* "pywrapfst.pyx":3071
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -31389,11 +31612,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, 3027, __pyx_L1_error)
+    __PYX_ERR(0, 3071, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3026
+  /* "pywrapfst.pyx":3070
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31412,7 +31635,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3031
+/* "pywrapfst.pyx":3075
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31439,7 +31662,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3032
+  /* "pywrapfst.pyx":3076
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -31449,15 +31672,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, 3032, __pyx_L1_error)
+    __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, 3032, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3031
+  /* "pywrapfst.pyx":3075
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31476,7 +31699,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3034
+/* "pywrapfst.pyx":3078
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31487,12 +31710,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
 /* Python wrapper */
 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) {
-  __pyx_t_10basictypes_int64 __pyx_v_value;
+  int64 __pyx_v_value;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3034, __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, 3078, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31500,19 +31723,19 @@ static int __pyx_pw_9pywrapfst_3Arc_6olabel_3__set__(PyObject *__pyx_v_self, PyO
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_value));
+  __pyx_r = __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((int64)__pyx_v_value));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value) {
+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
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3035
+  /* "pywrapfst.pyx":3079
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -31521,11 +31744,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, 3035, __pyx_L1_error)
+    __PYX_ERR(0, 3079, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3034
+  /* "pywrapfst.pyx":3078
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31544,7 +31767,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3039
+/* "pywrapfst.pyx":3083
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31572,19 +31795,19 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3040
+  /* "pywrapfst.pyx":3084
  * 
  *     def __get__(self):
  *       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, 3040, __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, 3084, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3041
+  /* "pywrapfst.pyx":3085
  *     def __get__(self):
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
@@ -31593,15 +31816,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3041, __pyx_L1_error)
+    __PYX_ERR(0, 3085, __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, 3041, __pyx_L1_error)
+    __PYX_ERR(0, 3085, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":3042
+  /* "pywrapfst.pyx":3086
  *       cdef Weight weight = Weight.__new__(Weight)
  *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  *       return weight             # <<<<<<<<<<<<<<
@@ -31613,7 +31836,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3039
+  /* "pywrapfst.pyx":3083
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31633,7 +31856,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3044
+/* "pywrapfst.pyx":3088
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -31660,21 +31883,21 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   fst::script::WeightClass __pyx_t_1;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3045
+  /* "pywrapfst.pyx":3089
  * 
  *     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, 3045, __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, 3089, __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, 3045, __pyx_L1_error)
+    __PYX_ERR(0, 3089, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3044
+  /* "pywrapfst.pyx":3088
  *       return weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
@@ -31693,7 +31916,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3049
+/* "pywrapfst.pyx":3093
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31720,7 +31943,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3050
+  /* "pywrapfst.pyx":3094
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -31730,15 +31953,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, 3050, __pyx_L1_error)
+    __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, 3050, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3049
+  /* "pywrapfst.pyx":3093
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31757,7 +31980,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3052
+/* "pywrapfst.pyx":3096
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31768,12 +31991,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
 /* Python wrapper */
 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) {
-  __pyx_t_10basictypes_int64 __pyx_v_value;
+  int64 __pyx_v_value;
   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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3052, __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, 3096, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31781,19 +32004,19 @@ static int __pyx_pw_9pywrapfst_3Arc_9nextstate_3__set__(PyObject *__pyx_v_self,
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((__pyx_t_10basictypes_int64)__pyx_v_value));
+  __pyx_r = __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_self), ((int64)__pyx_v_value));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, __pyx_t_10basictypes_int64 __pyx_v_value) {
+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
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3053
+  /* "pywrapfst.pyx":3097
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -31802,11 +32025,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, 3053, __pyx_L1_error)
+    __PYX_ERR(0, 3097, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3052
+  /* "pywrapfst.pyx":3096
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31856,7 +32079,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__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -31909,7 +32132,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__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -31932,7 +32155,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3056
+/* "pywrapfst.pyx":3100
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -31950,19 +32173,19 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("_init_Arc", 0);
 
-  /* "pywrapfst.pyx":3057
+  /* "pywrapfst.pyx":3101
  * 
  * 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)
  */
-  __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, 3057, __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, 3101, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3058
+  /* "pywrapfst.pyx":3102
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
  *   cdef Weight weight = Weight.__new__(Weight)
  *   weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
@@ -31971,11 +32194,11 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  */
   if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3058, __pyx_L1_error)
+    __PYX_ERR(0, 3102, __pyx_L1_error)
   }
   __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":3059
+  /* "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)             # <<<<<<<<<<<<<<
@@ -31983,13 +32206,13 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
  * 
  */
   __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, 3059, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3059, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3059, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3059, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3103, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
@@ -32003,14 +32226,14 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   __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, 3059, __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, 3103, __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":3056
+  /* "pywrapfst.pyx":3100
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
@@ -32033,7 +32256,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3070
+/* "pywrapfst.pyx":3114
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32063,17 +32286,17 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3071
+  /* "pywrapfst.pyx":3115
  * 
  *   def __repr__(self):
  *     return "<ArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
  * 
- *   def __init__(self, _Fst ifst, int64 state):
+ *   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, 3071, __pyx_L1_error)
+  __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, 3071, __pyx_L1_error)
+  __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))) {
@@ -32088,14 +32311,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   __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, 3071, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3115, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3070
+  /* "pywrapfst.pyx":3114
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -32117,10 +32340,10 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3073
+/* "pywrapfst.pyx":3117
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
+ *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  */
@@ -32128,8 +32351,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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;
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
+  int64 __pyx_v_state;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -32156,11 +32379,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, 3073, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3117, __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, 3073, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3117, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32168,18 +32391,18 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3073, __pyx_L3_error)
+    __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)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3073, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3117, __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, 3073, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3117, __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 */
@@ -32191,7 +32414,7 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int64 __pyx_v_state) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -32201,28 +32424,28 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   std::shared_ptr<fst::script::FstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3074
+  /* "pywrapfst.pyx":3118
  * 
- *   def __init__(self, _Fst ifst, int64 state):
+ *   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.
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3074, __pyx_L1_error)
+    __PYX_ERR(0, 3118, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3075
- *   def __init__(self, _Fst ifst, int64 state):
+    /* "pywrapfst.pyx":3119
+ *   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, 3075, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3119, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32236,23 +32459,23 @@ 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, 3075, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3119, __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, 3075, __pyx_L1_error)
+    __PYX_ERR(0, 3119, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3074
+    /* "pywrapfst.pyx":3118
  * 
- *   def __init__(self, _Fst ifst, int64 state):
+ *   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.
  */
   }
 
-  /* "pywrapfst.pyx":3077
+  /* "pywrapfst.pyx":3121
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -32261,16 +32484,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, 3077, __pyx_L1_error)
+    __PYX_ERR(0, 3121, __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, 3077, __pyx_L1_error)
+    __PYX_ERR(0, 3121, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3078
+  /* "pywrapfst.pyx":3122
  *     # 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))             # <<<<<<<<<<<<<<
@@ -32279,18 +32502,18 @@ 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, 3078, __pyx_L1_error)
+    __PYX_ERR(0, 3122, __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, 3078, __pyx_L1_error)
+    __PYX_ERR(0, 3122, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3073
+  /* "pywrapfst.pyx":3117
  *     return "<ArcIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _Fst ifst, int64 state):             # <<<<<<<<<<<<<<
+ *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  */
@@ -32309,7 +32532,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3081
+/* "pywrapfst.pyx":3125
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32335,7 +32558,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3082
+  /* "pywrapfst.pyx":3126
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -32347,7 +32570,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3081
+  /* "pywrapfst.pyx":3125
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32362,7 +32585,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3085
+/* "pywrapfst.pyx":3129
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32391,7 +32614,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3086
+  /* "pywrapfst.pyx":3130
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32400,12 +32623,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, 3086, __pyx_L1_error)
+    __PYX_ERR(0, 3130, __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":3087
+    /* "pywrapfst.pyx":3131
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -32413,9 +32636,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, 3087, __pyx_L1_error)
+    __PYX_ERR(0, 3131, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3086
+    /* "pywrapfst.pyx":3130
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32424,7 +32647,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":3088
+  /* "pywrapfst.pyx":3132
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -32433,14 +32656,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, 3088, __pyx_L1_error)
+    __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, 3088, __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_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3089
+  /* "pywrapfst.pyx":3133
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -32449,11 +32672,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, 3089, __pyx_L1_error)
+    __PYX_ERR(0, 3133, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3090
+  /* "pywrapfst.pyx":3134
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -32465,7 +32688,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3085
+  /* "pywrapfst.pyx":3129
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32485,7 +32708,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3092
+/* "pywrapfst.pyx":3136
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32512,7 +32735,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, 3092, __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, 3136, __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);
@@ -32528,10 +32751,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, 3092, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3136, __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, 3092, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32550,7 +32773,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3101
+  /* "pywrapfst.pyx":3145
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -32559,12 +32782,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, 3101, __pyx_L1_error)
+    __PYX_ERR(0, 3145, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3092
+  /* "pywrapfst.pyx":3136
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32605,7 +32828,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   PyObject *__pyx_t_1 = NULL;
   __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, 3092, __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, 3136, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32622,7 +32845,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3103
+/* "pywrapfst.pyx":3147
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32631,14 +32854,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_11flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint8 __pyx_r;
+static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+  uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint8 __pyx_t_5;
+  uint8 __pyx_t_5;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -32649,7 +32872,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(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_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3103, __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, 3147, __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);
@@ -32665,10 +32888,10 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
         }
         __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, 3103, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3147, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3103, __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, 3147, __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;
@@ -32687,7 +32910,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":3112
+  /* "pywrapfst.pyx":3156
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -32696,12 +32919,12 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3112, __pyx_L1_error)
+    __PYX_ERR(0, 3156, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3103
+  /* "pywrapfst.pyx":3147
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32742,7 +32965,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3103, __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, 3147, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32759,7 +32982,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3114
+/* "pywrapfst.pyx":3158
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -32784,7 +33007,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, 3114, __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, 3158, __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);
@@ -32800,7 +33023,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, 3114, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3158, __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;
@@ -32820,7 +33043,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3120
+  /* "pywrapfst.pyx":3164
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -32829,11 +33052,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, 3120, __pyx_L1_error)
+    __PYX_ERR(0, 3164, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3114
+  /* "pywrapfst.pyx":3158
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -32873,7 +33096,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 3114, __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, 3158, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32890,7 +33113,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3122
+/* "pywrapfst.pyx":3166
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -32917,7 +33140,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, 3122, __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, 3166, __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);
@@ -32933,10 +33156,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, 3122, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3166, __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, 3122, __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, 3166, __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;
@@ -32955,7 +33178,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3131
+  /* "pywrapfst.pyx":3175
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -32964,12 +33187,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, 3131, __pyx_L1_error)
+    __PYX_ERR(0, 3175, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3122
+  /* "pywrapfst.pyx":3166
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33010,7 +33233,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   PyObject *__pyx_t_1 = NULL;
   __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, 3122, __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, 3166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33027,7 +33250,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3133
+/* "pywrapfst.pyx":3177
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33052,7 +33275,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, 3133, __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, 3177, __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);
@@ -33068,7 +33291,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, 3133, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3177, __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;
@@ -33088,7 +33311,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     #endif
   }
 
-  /* "pywrapfst.pyx":3139
+  /* "pywrapfst.pyx":3183
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -33097,11 +33320,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, 3139, __pyx_L1_error)
+    __PYX_ERR(0, 3183, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3133
+  /* "pywrapfst.pyx":3177
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33141,7 +33364,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3133, __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, 3177, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33158,7 +33381,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3141
+/* "pywrapfst.pyx":3185
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33184,10 +33407,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, 3141, __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, 3185, __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, 3141, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3185, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33203,7 +33426,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, 3141, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3185, __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;
@@ -33223,7 +33446,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3150
+  /* "pywrapfst.pyx":3194
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -33232,11 +33455,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, 3150, __pyx_L1_error)
+    __PYX_ERR(0, 3194, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3141
+  /* "pywrapfst.pyx":3185
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33266,7 +33489,7 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self
   __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, 3141, __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, 3185, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -33287,7 +33510,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 3141, __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, 3185, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33304,7 +33527,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3152
+/* "pywrapfst.pyx":3196
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33313,7 +33536,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
  */
 
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
+static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -33333,12 +33556,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, 3152, __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, 3196, __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, 3152, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3196, __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, 3152, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3196, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -33356,7 +33579,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, 3152, __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, 3196, __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;
@@ -33366,7 +33589,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, 3152, __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, 3196, __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;
@@ -33374,7 +33597,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, 3152, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3196, __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;
@@ -33385,7 +33608,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, 3152, __pyx_L1_error)
+          __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_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -33407,7 +33630,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":3162
+  /* "pywrapfst.pyx":3206
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -33416,11 +33639,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, 3162, __pyx_L1_error)
+    __PYX_ERR(0, 3206, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3152
+  /* "pywrapfst.pyx":3196
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33447,8 +33670,8 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint8 __pyx_v_flags;
-  __pyx_t_10basictypes_uint8 __pyx_v_mask;
+  uint8 __pyx_v_flags;
+  uint8 __pyx_v_mask;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -33475,11 +33698,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, 3152, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3196, __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, 3152, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3196, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -33487,12 +33710,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3152, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3152, __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, 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)
   }
   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, 3152, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3196, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -33505,13 +33728,13 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 3152, __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, 3196, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33528,7 +33751,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3164
+/* "pywrapfst.pyx":3208
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33554,7 +33777,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, 3164, __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, 3208, __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);
@@ -33571,7 +33794,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, 3164, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3208, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -33592,7 +33815,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3170
+  /* "pywrapfst.pyx":3214
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -33602,15 +33825,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, 3170, __pyx_L1_error)
+    __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, 3170, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3164
+  /* "pywrapfst.pyx":3208
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33652,7 +33875,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3164, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33700,7 +33923,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__23, 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;
@@ -33753,7 +33976,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__24, 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;
@@ -33776,7 +33999,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3182
+/* "pywrapfst.pyx":3226
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -33806,17 +34029,17 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3183
+  /* "pywrapfst.pyx":3227
  * 
  *   def __repr__(self):
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
  * 
- *   def __init__(self, _MutableFst ifst, int64 state):
+ *   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, 3183, __pyx_L1_error)
+  __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, 3183, __pyx_L1_error)
+  __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))) {
@@ -33831,14 +34054,14 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   __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, 3183, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3227, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3182
+  /* "pywrapfst.pyx":3226
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -33860,10 +34083,10 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3185
+/* "pywrapfst.pyx":3229
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
+ *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  */
@@ -33871,8 +34094,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 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;
-  __pyx_t_10basictypes_int64 __pyx_v_state;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst = 0;
+  int64 __pyx_v_state;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -33899,11 +34122,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, 3185, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3229, __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, 3185, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3229, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -33911,18 +34134,18 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3185, __pyx_L3_error)
+    __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)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3185, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3229, __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, 3185, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3229, __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 */
@@ -33934,7 +34157,7 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__MutableFst *__pyx_v_ifst, __pyx_t_10basictypes_int64 __pyx_v_state) {
+static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst, int64 __pyx_v_state) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -33944,28 +34167,28 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   std::shared_ptr<fst::script::MutableFstClass>  __pyx_t_5;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3186
+  /* "pywrapfst.pyx":3230
  * 
- *   def __init__(self, _MutableFst ifst, int64 state):
+ *   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.
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3186, __pyx_L1_error)
+    __PYX_ERR(0, 3230, __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":3187
- *   def __init__(self, _MutableFst ifst, int64 state):
+    /* "pywrapfst.pyx":3231
+ *   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, 3187, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3231, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -33979,23 +34202,23 @@ 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, 3187, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3231, __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, 3187, __pyx_L1_error)
+    __PYX_ERR(0, 3231, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3186
+    /* "pywrapfst.pyx":3230
  * 
- *   def __init__(self, _MutableFst ifst, int64 state):
+ *   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.
  */
   }
 
-  /* "pywrapfst.pyx":3189
+  /* "pywrapfst.pyx":3233
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -34004,36 +34227,36 @@ 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, 3189, __pyx_L1_error)
+    __PYX_ERR(0, 3233, __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, 3189, __pyx_L1_error)
+    __PYX_ERR(0, 3233, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3190
+  /* "pywrapfst.pyx":3234
  *     # 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))             # <<<<<<<<<<<<<<
  * 
- *   # Magic method used to get a Pythonic Iterator API out of the C++ API
+ *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3190, __pyx_L1_error)
+    __PYX_ERR(0, 3234, __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, 3190, __pyx_L1_error)
+    __PYX_ERR(0, 3234, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3185
+  /* "pywrapfst.pyx":3229
  *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
+ *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  */
@@ -34053,9 +34276,9 @@ 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":3193
+/* "pywrapfst.pyx":3237
  * 
- *   # Magic method used to get a Pythonic Iterator API out of the C++ API
+ *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
  *     while not self.done():
  *       yield self.value()
@@ -34083,7 +34306,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   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, 3193, __pyx_L1_error)
+    __PYX_ERR(0, 3237, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -34091,7 +34314,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, 3193, __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, 3237, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -34123,10 +34346,10 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3193, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3237, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3194
- *   # Magic method used to get a Pythonic Iterator API out of the C++ API
+  /* "pywrapfst.pyx":3238
+ *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):
  *     while not self.done():             # <<<<<<<<<<<<<<
  *       yield self.value()
@@ -34135,12 +34358,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, 3194, __pyx_L1_error)
+      __PYX_ERR(0, 3238, __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":3195
+    /* "pywrapfst.pyx":3239
  *   def __iter__(self):
  *     while not self.done():
  *       yield self.value()             # <<<<<<<<<<<<<<
@@ -34149,9 +34372,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, 3195, __pyx_L1_error)
+      __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, 3195, __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_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -34162,9 +34385,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, 3195, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3239, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3196
+    /* "pywrapfst.pyx":3240
  *     while not self.done():
  *       yield self.value()
  *       self.next()             # <<<<<<<<<<<<<<
@@ -34173,15 +34396,15 @@ 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, 3196, __pyx_L1_error)
+      __PYX_ERR(0, 3240, __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":3193
+  /* "pywrapfst.pyx":3237
  * 
- *   # Magic method used to get a Pythonic Iterator API out of the C++ API
+ *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
  *     while not self.done():
  *       yield self.value()
@@ -34204,7 +34427,7 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3198
+/* "pywrapfst.pyx":3242
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34231,7 +34454,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, 3198, __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, 3242, __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);
@@ -34247,10 +34470,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, 3198, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3242, __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, 3198, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34269,7 +34492,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3207
+  /* "pywrapfst.pyx":3251
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -34278,12 +34501,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, 3207, __pyx_L1_error)
+    __PYX_ERR(0, 3251, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3198
+  /* "pywrapfst.pyx":3242
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34324,7 +34547,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   PyObject *__pyx_t_1 = NULL;
   __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, 3198, __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, 3242, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34341,7 +34564,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3209
+/* "pywrapfst.pyx":3253
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34350,14 +34573,14 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
  */
 
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_10flags(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_uint8 __pyx_r;
+static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+  uint8 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_uint8 __pyx_t_5;
+  uint8 __pyx_t_5;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34368,7 +34591,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(
     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, 3209, __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, 3253, __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);
@@ -34384,10 +34607,10 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(
         }
         __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, 3209, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3253, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3209, __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, 3253, __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;
@@ -34406,7 +34629,7 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(
     #endif
   }
 
-  /* "pywrapfst.pyx":3218
+  /* "pywrapfst.pyx":3262
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -34415,12 +34638,12 @@ static __pyx_t_10basictypes_uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3218, __pyx_L1_error)
+    __PYX_ERR(0, 3262, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3209
+  /* "pywrapfst.pyx":3253
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34461,7 +34684,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 3209, __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, 3253, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34478,7 +34701,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3220
+/* "pywrapfst.pyx":3264
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34503,7 +34726,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, 3220, __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, 3264, __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);
@@ -34519,7 +34742,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, 3220, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3264, __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;
@@ -34539,7 +34762,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3226
+  /* "pywrapfst.pyx":3270
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -34548,11 +34771,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, 3226, __pyx_L1_error)
+    __PYX_ERR(0, 3270, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3220
+  /* "pywrapfst.pyx":3264
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34592,7 +34815,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 3220, __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, 3264, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34609,7 +34832,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3228
+/* "pywrapfst.pyx":3272
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -34636,7 +34859,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, 3228, __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, 3272, __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);
@@ -34652,10 +34875,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, 3228, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3272, __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, 3228, __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, 3272, __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;
@@ -34674,7 +34897,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3237
+  /* "pywrapfst.pyx":3281
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -34683,12 +34906,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, 3237, __pyx_L1_error)
+    __PYX_ERR(0, 3281, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3228
+  /* "pywrapfst.pyx":3272
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -34729,7 +34952,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   PyObject *__pyx_t_1 = NULL;
   __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, 3228, __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, 3272, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34746,7 +34969,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3239
+/* "pywrapfst.pyx":3283
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -34771,7 +34994,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, 3239, __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, 3283, __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);
@@ -34787,7 +35010,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, 3239, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3283, __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;
@@ -34807,7 +35030,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":3245
+  /* "pywrapfst.pyx":3289
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -34816,11 +35039,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, 3245, __pyx_L1_error)
+    __PYX_ERR(0, 3289, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3239
+  /* "pywrapfst.pyx":3283
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -34860,7 +35083,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __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, 3239, __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, 3283, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34877,7 +35100,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3247
+/* "pywrapfst.pyx":3291
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -34903,10 +35126,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, 3247, __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, 3291, __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, 3247, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3291, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -34922,7 +35145,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, 3247, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3291, __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;
@@ -34942,7 +35165,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3256
+  /* "pywrapfst.pyx":3300
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -34951,11 +35174,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, 3256, __pyx_L1_error)
+    __PYX_ERR(0, 3300, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3247
+  /* "pywrapfst.pyx":3291
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -34985,7 +35208,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx
   __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, 3247, __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, 3291, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -35006,7 +35229,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   PyObject *__pyx_t_1 = NULL;
   __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, 3247, __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, 3291, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35023,7 +35246,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3258
+/* "pywrapfst.pyx":3302
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35032,7 +35255,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
  */
 
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
+static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -35052,12 +35275,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, 3258, __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, 3302, __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, 3258, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3302, __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, 3258, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3302, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -35075,7 +35298,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, 3258, __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, 3302, __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;
@@ -35085,7 +35308,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, 3258, __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, 3302, __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;
@@ -35093,7 +35316,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, 3258, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3302, __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;
@@ -35104,7 +35327,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, 3258, __pyx_L1_error)
+          __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_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -35126,7 +35349,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3268
+  /* "pywrapfst.pyx":3312
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -35135,11 +35358,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, 3268, __pyx_L1_error)
+    __PYX_ERR(0, 3312, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3258
+  /* "pywrapfst.pyx":3302
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35166,8 +35389,8 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_18MutableArcIterator_19set_flags[] = "\n    set_flags(self, flags, mask)\n\n    Sets the current iterator behavioral flags.\n\n    Args:\n      flags: The properties to be set.\n      mask: A mask to be applied to the `flags` argument before setting them.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  __pyx_t_10basictypes_uint8 __pyx_v_flags;
-  __pyx_t_10basictypes_uint8 __pyx_v_mask;
+  uint8 __pyx_v_flags;
+  uint8 __pyx_v_mask;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -35194,11 +35417,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, 3258, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3302, __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, 3258, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3302, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -35206,12 +35429,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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __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, 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)
   }
   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, 3258, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3302, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -35224,13 +35447,13 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, __pyx_t_10basictypes_uint8 __pyx_v_flags, __pyx_t_10basictypes_uint8 __pyx_v_mask) {
+static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_v_self, uint8 __pyx_v_flags, uint8 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 3258, __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, 3302, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35247,7 +35470,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3270
+/* "pywrapfst.pyx":3314
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35272,7 +35495,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, 3270, __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, 3314, __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);
@@ -35288,7 +35511,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, 3270, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3314, __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;
@@ -35308,7 +35531,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3279
+  /* "pywrapfst.pyx":3323
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -35317,15 +35540,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, 3279, __pyx_L1_error)
+    __PYX_ERR(0, 3323, __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, 3279, __pyx_L1_error)
+    __PYX_ERR(0, 3323, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3270
+  /* "pywrapfst.pyx":3314
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35352,7 +35575,7 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *
   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, 3270, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3314, __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 */
@@ -35370,7 +35593,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   PyObject *__pyx_t_1 = NULL;
   __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, 3270, __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, 3314, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35387,7 +35610,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3281
+/* "pywrapfst.pyx":3325
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35413,7 +35636,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, 3281, __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, 3325, __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);
@@ -35430,7 +35653,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, 3281, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3325, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -35451,7 +35674,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3287
+  /* "pywrapfst.pyx":3331
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -35461,15 +35684,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, 3287, __pyx_L1_error)
+    __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, 3287, __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3281
+  /* "pywrapfst.pyx":3325
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35511,7 +35734,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   PyObject *__pyx_t_1 = NULL;
   __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, 3281, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35559,7 +35782,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__25, 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;
@@ -35612,7 +35835,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__26, 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;
@@ -35635,7 +35858,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3301
+/* "pywrapfst.pyx":3345
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -35665,17 +35888,17 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   PyObject *__pyx_t_4 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3302
+  /* "pywrapfst.pyx":3346
  * 
  *   def __repr__(self):
  *     return "<StateIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
  * 
- *   def __init__(self, _Fst ifst):
+ *   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, 3302, __pyx_L1_error)
+  __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, 3302, __pyx_L1_error)
+  __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))) {
@@ -35690,14 +35913,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   __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, 3302, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3346, __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;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3301
+  /* "pywrapfst.pyx":3345
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -35719,10 +35942,10 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3304
+/* "pywrapfst.pyx":3348
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  */
@@ -35730,7 +35953,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
 /* Python wrapper */
 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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -35753,24 +35976,24 @@ 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, 3304, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3348, __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_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)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, 3304, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3348, __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, 3304, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3348, __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 */
@@ -35782,14 +36005,14 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::shared_ptr<fst::script::FstClass>  __pyx_t_1;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3306
- *   def __init__(self, _Fst ifst):
+  /* "pywrapfst.pyx":3350
+ *   def __init__(self, Fst ifst):
  *     # 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)))
@@ -35797,16 +36020,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, 3306, __pyx_L1_error)
+    __PYX_ERR(0, 3350, __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, 3306, __pyx_L1_error)
+    __PYX_ERR(0, 3350, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3307
+  /* "pywrapfst.pyx":3351
  *     # 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)))             # <<<<<<<<<<<<<<
@@ -35815,18 +36038,18 @@ 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, 3307, __pyx_L1_error)
+    __PYX_ERR(0, 3351, __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, 3307, __pyx_L1_error)
+    __PYX_ERR(0, 3351, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3304
+  /* "pywrapfst.pyx":3348
  *     return "<StateIterator at 0x{:x}>".format(id(self))
  * 
- *   def __init__(self, _Fst ifst):             # <<<<<<<<<<<<<<
+ *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  */
@@ -35842,7 +36065,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3310
+/* "pywrapfst.pyx":3354
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -35868,7 +36091,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3311
+  /* "pywrapfst.pyx":3355
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -35880,7 +36103,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3310
+  /* "pywrapfst.pyx":3354
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -35895,7 +36118,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3314
+/* "pywrapfst.pyx":3358
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -35917,14 +36140,14 @@ static PyObject *__pyx_pw_9pywrapfst_13StateIterator_7__next__(PyObject *__pyx_v
 }
 
 static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self) {
-  __pyx_t_10basictypes_int64 __pyx_v_result;
+  int64 __pyx_v_result;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3315
+  /* "pywrapfst.pyx":3359
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -35933,12 +36156,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, 3315, __pyx_L1_error)
+    __PYX_ERR(0, 3359, __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":3316
+    /* "pywrapfst.pyx":3360
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -35946,9 +36169,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, 3316, __pyx_L1_error)
+    __PYX_ERR(0, 3360, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3315
+    /* "pywrapfst.pyx":3359
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -35957,7 +36180,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3317
+  /* "pywrapfst.pyx":3361
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -35966,11 +36189,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, 3317, __pyx_L1_error)
+    __PYX_ERR(0, 3361, __pyx_L1_error)
   }
   __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3318
+  /* "pywrapfst.pyx":3362
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -35979,11 +36202,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, 3318, __pyx_L1_error)
+    __PYX_ERR(0, 3362, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3319
+  /* "pywrapfst.pyx":3363
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -35991,13 +36214,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, 3319, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3363, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3314
+  /* "pywrapfst.pyx":3358
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -36016,7 +36239,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3321
+/* "pywrapfst.pyx":3365
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36043,7 +36266,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, 3321, __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, 3365, __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);
@@ -36059,10 +36282,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, 3321, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3365, __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, 3321, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36081,7 +36304,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3330
+  /* "pywrapfst.pyx":3374
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -36090,12 +36313,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, 3330, __pyx_L1_error)
+    __PYX_ERR(0, 3374, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3321
+  /* "pywrapfst.pyx":3365
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36136,7 +36359,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 3321, __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, 3365, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36153,7 +36376,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3332
+/* "pywrapfst.pyx":3376
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36178,7 +36401,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, 3332, __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, 3376, __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);
@@ -36194,7 +36417,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, 3332, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3376, __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;
@@ -36214,7 +36437,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3338
+  /* "pywrapfst.pyx":3382
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -36223,11 +36446,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, 3338, __pyx_L1_error)
+    __PYX_ERR(0, 3382, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3332
+  /* "pywrapfst.pyx":3376
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36267,7 +36490,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   PyObject *__pyx_t_1 = NULL;
   __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, 3332, __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, 3376, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36284,7 +36507,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3340
+/* "pywrapfst.pyx":3384
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36309,7 +36532,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, 3340, __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, 3384, __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);
@@ -36325,7 +36548,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, 3340, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3384, __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;
@@ -36345,7 +36568,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":3346
+  /* "pywrapfst.pyx":3390
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -36354,11 +36577,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, 3346, __pyx_L1_error)
+    __PYX_ERR(0, 3390, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3340
+  /* "pywrapfst.pyx":3384
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36398,7 +36621,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __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, 3340, __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, 3384, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36415,7 +36638,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3348
+/* "pywrapfst.pyx":3392
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36424,14 +36647,14 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
  */
 
 static PyObject *__pyx_pw_9pywrapfst_13StateIterator_15value(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
-  __pyx_t_10basictypes_int64 __pyx_r;
+static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfst_StateIterator *__pyx_v_self, int __pyx_skip_dispatch) {
+  int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
+  int64 __pyx_t_5;
   __Pyx_RefNannySetupContext("value", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -36442,7 +36665,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(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_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3348, __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, 3392, __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);
@@ -36458,10 +36681,10 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(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, 3348, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3392, __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3348, __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, 3392, __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;
@@ -36480,7 +36703,7 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":3354
+  /* "pywrapfst.pyx":3398
  *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -36489,12 +36712,12 @@ static __pyx_t_10basictypes_int64 __pyx_f_9pywrapfst_13StateIterator_value(struc
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3354, __pyx_L1_error)
+    __PYX_ERR(0, 3398, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3348
+  /* "pywrapfst.pyx":3392
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36535,7 +36758,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   PyObject *__pyx_t_1 = NULL;
   __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, 3348, __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, 3392, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36583,7 +36806,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__27, 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;
@@ -36636,7 +36859,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__28, 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;
@@ -36659,20 +36882,20 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3360
+/* "pywrapfst.pyx":3404
  * 
  * 
- * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
+ * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
  *                float delta=fst.kDelta,
  *                map_type=b"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__29;
+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);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3364
+  /* "pywrapfst.pyx":3408
  *                map_type=b"identity",
  *                double power=1.,
  *                weight=None):             # <<<<<<<<<<<<<<
@@ -36682,7 +36905,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
   enum fst::script::MapType __pyx_v_map_type_enum;
   fst::script::WeightClass __pyx_v_wc;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -36708,27 +36931,27 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
   }
 
-  /* "pywrapfst.pyx":3366
+  /* "pywrapfst.pyx":3410
  *                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
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3366, __pyx_L1_error)
+  __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);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3367
+    /* "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:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3367, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3411, __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, 3367, __pyx_L1_error)
+    __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))) {
@@ -36742,7 +36965,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     }
     __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, 3367, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3411, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -36758,14 +36981,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     __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, 3367, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3411, __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, 3367, __pyx_L1_error)
+    __PYX_ERR(0, 3411, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3366
+    /* "pywrapfst.pyx":3410
  *                weight=None):
  *   cdef fst.MapType map_type_enum
  *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
@@ -36774,7 +36997,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
   }
 
-  /* "pywrapfst.pyx":3369
+  /* "pywrapfst.pyx":3413
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc
  *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
@@ -36784,7 +37007,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   __pyx_t_2 = ((__pyx_v_map_type_enum == fst::script::TIMES_MAPPER) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3370
+    /* "pywrapfst.pyx":3414
  *   cdef fst.WeightClass wc
  *   if map_type_enum == fst.TIMES_MAPPER:
  *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -36793,12 +37016,12 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3370, __pyx_L1_error)
+      __PYX_ERR(0, 3414, __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, 3370, __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;
 
-    /* "pywrapfst.pyx":3369
+    /* "pywrapfst.pyx":3413
  *     raise FstArgError("Unknown map type: {!r}".format(map_type))
  *   cdef fst.WeightClass wc
  *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
@@ -36808,7 +37031,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
     goto __pyx_L4;
   }
 
-  /* "pywrapfst.pyx":3372
+  /* "pywrapfst.pyx":3416
  *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
  *   else:
  *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
@@ -36818,14 +37041,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3372, __pyx_L1_error)
+      __PYX_ERR(0, 3416, __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, 3372, __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_L4:;
 
-  /* "pywrapfst.pyx":3373
+  /* "pywrapfst.pyx":3417
  *   else:
  *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))             # <<<<<<<<<<<<<<
@@ -36835,18 +37058,18 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   __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, 3373, __pyx_L1_error)
+    __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_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3373, __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3360
+  /* "pywrapfst.pyx":3404
  * 
  * 
- * cdef _Fst _map(_Fst ifst,             # <<<<<<<<<<<<<<
+ * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
  *                float delta=fst.kDelta,
  *                map_type=b"identity",
  */
@@ -36866,29 +37089,29 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst__map(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3376
+/* "pywrapfst.pyx":3420
  * 
  * 
- * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
- *                   map_type=b"identity",
+ * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
+ *                  float delta=fst.kDelta,
+ *                  map_type=b"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__30;
+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);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3380
- *                   map_type=b"identity",
- *                   double power=1.,
- *                   weight=None):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3424
+ *                  map_type=b"identity",
+ *                  double power=1.,
+ *                  weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   arcmap(ifst, delta=0.0009765625, map_type="identity", power=1., weight=None)
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst__map __pyx_t_2;
@@ -36908,7 +37131,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3421
+  /* "pywrapfst.pyx":3465
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, delta, map_type, power, weight)             # <<<<<<<<<<<<<<
@@ -36921,18 +37144,18 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
   __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, 3421, __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, 3465, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3376
+  /* "pywrapfst.pyx":3420
  * 
  * 
- * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
- *                   map_type=b"identity",
+ * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
+ *                  float delta=fst.kDelta,
+ *                  map_type=b"identity",
  */
 
   /* function exit code */
@@ -36950,7 +37173,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_
 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 PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   PyObject *__pyx_v_map_type = 0;
   double __pyx_v_power;
@@ -36963,10 +37186,10 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
     PyObject* values[5] = {0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_identity);
 
-    /* "pywrapfst.pyx":3380
- *                   map_type=b"identity",
- *                   double power=1.,
- *                   weight=None):             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":3424
+ *                  map_type=b"identity",
+ *                  double power=1.,
+ *                  weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   arcmap(ifst, delta=0.0009765625, map_type="identity", power=1., weight=None)
  */
@@ -37019,7 +37242,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, 3376, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3420, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37036,15 +37259,15 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3377, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3421, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__30;
+      __pyx_v_delta = __pyx_k__31;
     }
     __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, 3379, __pyx_L3_error)
+      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3423, __pyx_L3_error)
     } else {
       __pyx_v_power = ((double)1.);
     }
@@ -37052,21 +37275,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, 3376, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3420, __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, 3376, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3420, __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":3376
+  /* "pywrapfst.pyx":3420
  * 
  * 
- * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
- *                   map_type=b"identity",
+ * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
+ *                  float delta=fst.kDelta,
+ *                  map_type=b"identity",
  */
 
   /* function exit code */
@@ -37078,7 +37301,7 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_map_type, double __pyx_v_power, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37090,7 +37313,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, 3376, __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, 3420, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37107,29 +37330,29 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3424
+/* "pywrapfst.pyx":3468
  * 
  * 
- * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
- *                           compose_filter=b"auto",
+ * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                          Fst ifst2,
+ *                          compose_filter=b"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) {
+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);
 
-  /* "pywrapfst.pyx":3427
- *                           _Fst ifst2,
- *                           compose_filter=b"auto",
- *                           bool connect=True):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3471
+ *                          Fst ifst2,
+ *                          compose_filter=b"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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
@@ -37144,7 +37367,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
     }
   }
 
-  /* "pywrapfst.pyx":3451
+  /* "pywrapfst.pyx":3495
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -37153,21 +37376,21 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3451, __pyx_L1_error)
+    __PYX_ERR(0, 3495, __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":3455
+  /* "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())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3455, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3455, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":3453
+  /* "pywrapfst.pyx":3497
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
@@ -37176,7 +37399,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3456
+  /* "pywrapfst.pyx":3500
  *       connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -37185,15 +37408,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3456, __pyx_L1_error)
+    __PYX_ERR(0, 3500, __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, 3456, __pyx_L1_error)
+    __PYX_ERR(0, 3500, __pyx_L1_error)
   }
   fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3457
+  /* "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())             # <<<<<<<<<<<<<<
@@ -37201,18 +37424,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
  * 
  */
   __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, 3457, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3424
+  /* "pywrapfst.pyx":3468
  * 
  * 
- * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
- *                           compose_filter=b"auto",
+ * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                          Fst ifst2,
+ *                          compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -37230,8 +37453,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_compose(struc
 static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_22compose[] = "\n  compose(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively composes two FSTs.\n\n  This operation computes the composition of two FSTs. If A transduces string\n  x to y with weight a and B transduces y to z with weight b, then their\n  composition transduces string x to z with weight a \\otimes b. The output\n  labels of the first transducer or the input labels of the second transducer\n  must be sorted (or otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_23compose(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
   PyObject *__pyx_r = 0;
@@ -37265,7 +37488,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, 3424, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3468, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37281,7 +37504,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, 3424, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3468, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37295,17 +37518,17 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
+    __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, 3427, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3471, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3427
- *                           _Fst ifst2,
- *                           compose_filter=b"auto",
- *                           bool connect=True):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3471
+ *                          Fst ifst2,
+ *                          compose_filter=b"auto",
+ *                          bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   compose(ifst1, ifst2, compose_filter="auto", connect=True)
  */
@@ -37314,22 +37537,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, 3424, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3468, __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, 3424, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3425, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_22compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3424
+  /* "pywrapfst.pyx":3468
  * 
  * 
- * cpdef _MutableFst compose(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
- *                           compose_filter=b"auto",
+ * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                          Fst ifst2,
+ *                          compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -37341,7 +37564,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37351,7 +37574,7 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   __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, 3424, __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, 3468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37368,20 +37591,20 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3460
+/* "pywrapfst.pyx":3504
  * 
  * 
- * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef Fst convert(Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
  *   """
  *   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) {
+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;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -37397,17 +37620,17 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
   }
 
-  /* "pywrapfst.pyx":3477
+  /* "pywrapfst.pyx":3521
  *     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))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3477, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":3479
+  /* "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))             # <<<<<<<<<<<<<<
@@ -37416,11 +37639,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3479, __pyx_L1_error)
+    __PYX_ERR(0, 3523, __pyx_L1_error)
   }
   __pyx_v_tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v_fst_type_string));
 
-  /* "pywrapfst.pyx":3481
+  /* "pywrapfst.pyx":3525
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -37430,16 +37653,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
   __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3482
+    /* "pywrapfst.pyx":3526
  *   # 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())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3482, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3526, __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, 3482, __pyx_L1_error)
+    __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))) {
@@ -37453,7 +37676,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     }
     __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, 3482, __pyx_L1_error)
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3526, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __pyx_t_6 = NULL;
@@ -37469,14 +37692,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
     __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, 3482, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3526, __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, 3482, __pyx_L1_error)
+    __PYX_ERR(0, 3526, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3481
+    /* "pywrapfst.pyx":3525
  *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
  *   # Script-land Convert returns a null pointer to signal failure.
  *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -37485,7 +37708,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":3483
+  /* "pywrapfst.pyx":3527
  *   if tfst.get() == NULL:
  *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
  *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -37493,16 +37716,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
  * 
  */
   __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, 3483, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3460
+  /* "pywrapfst.pyx":3504
  * 
  * 
- * cpdef _Fst convert(_Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef Fst convert(Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
  *   """
  *   convert(ifst, fst_type="")
  */
@@ -37526,7 +37749,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_convert(struct __pyx
 static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_24convert[] = "\n  convert(ifst, fst_type=\"\")\n\n  Constructively converts an FST to a new internal representation.\n\n  Args:\n    ifst: The input FST.\n    fst_type: A string indicating the FST type to convert to, or an empty string\n        if no conversion is desired.\n\n  Returns:\n    The input FST converted to the desired FST type.\n\n  Raises:\n    FstOpError: Conversion failed.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_fst_type = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -37559,7 +37782,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, 3460, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3504, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37570,18 +37793,18 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_fst_type = values[1];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3460, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3504, __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, 3460, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3504, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_24convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
@@ -37593,7 +37816,7 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type) {
+static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_fst_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -37602,7 +37825,7 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   __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, 3460, __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, 3504, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37619,34 +37842,34 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3486
+/* "pywrapfst.pyx":3530
  * 
  * 
- * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
- *                               float delta=fst.kShortestDelta,
- *                               det_type=b"functional",
+ * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
+ *                              float delta=fst.kShortestDelta,
+ *                              det_type=b"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__31;
+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);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__32;
-  __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
+  int64 __pyx_v_nstate = __pyx_k__33;
+  int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3491
- *                               int64 nstate=fst.kNoStateId,
- *                               int64 subsequential_label=0,
- *                               weight=None,             # <<<<<<<<<<<<<<
- *                               bool increment_subsequential_label=False):
+  /* "pywrapfst.pyx":3535
+ *                              int64 nstate=fst.kNoStateId,
+ *                              int64 subsequential_label=0,
+ *                              weight=None,             # <<<<<<<<<<<<<<
+ *                              bool increment_subsequential_label=False):
  *   """
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3492
- *                               int64 subsequential_label=0,
- *                               weight=None,
- *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3536
+ *                              int64 subsequential_label=0,
+ *                              weight=None,
+ *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
  *   """
  *   determinize(ifst, delta=1e-6, det_type="functional",
  */
@@ -37655,7 +37878,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
   fst::script::WeightClass __pyx_v_wc;
   enum fst::DeterminizeType __pyx_v_determinize_type_enum;
   std::unique_ptr<fst::script::DeterminizeOptions>  __pyx_v_opts;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   std::string __pyx_t_2;
@@ -37687,7 +37910,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
   }
 
-  /* "pywrapfst.pyx":3526
+  /* "pywrapfst.pyx":3570
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -37696,11 +37919,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3526, __pyx_L1_error)
+    __PYX_ERR(0, 3570, __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":3528
+  /* "pywrapfst.pyx":3572
  *   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(),             # <<<<<<<<<<<<<<
@@ -37709,29 +37932,29 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3528, __pyx_L1_error)
+    __PYX_ERR(0, 3572, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3529
+  /* "pywrapfst.pyx":3573
  *   # 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, 3528, __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, 3572, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3531
+  /* "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, 3531, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3575, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3532
+  /* "pywrapfst.pyx":3576
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),
  *                                 addr(determinize_type_enum)):             # <<<<<<<<<<<<<<
@@ -37740,7 +37963,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   __pyx_t_3 = ((!(fst::script::GetDeterminizeType(__pyx_t_2, (&__pyx_v_determinize_type_enum)) != 0)) != 0);
 
-  /* "pywrapfst.pyx":3531
+  /* "pywrapfst.pyx":3575
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -37749,16 +37972,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":3533
+    /* "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,
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3533, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3577, __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, 3533, __pyx_L1_error)
+    __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))) {
@@ -37772,7 +37995,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     }
     __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, 3533, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3577, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -37788,14 +38011,14 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
     __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, 3533, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3577, __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, 3533, __pyx_L1_error)
+    __PYX_ERR(0, 3577, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3531
+    /* "pywrapfst.pyx":3575
  *                                                      weight)
  *   cdef fst.DeterminizeType determinize_type_enum
  *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
@@ -37804,7 +38027,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   }
 
-  /* "pywrapfst.pyx":3535
+  /* "pywrapfst.pyx":3579
  *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
  *   cdef unique_ptr[fst.DeterminizeOptions] opts
  *   opts.reset(new fst.DeterminizeOptions(delta,             # <<<<<<<<<<<<<<
@@ -37813,7 +38036,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   __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));
 
-  /* "pywrapfst.pyx":3541
+  /* "pywrapfst.pyx":3585
  *                                         determinize_type_enum,
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -37822,11 +38045,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3541, __pyx_L1_error)
+    __PYX_ERR(0, 3585, __pyx_L1_error)
   }
   fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3542
+  /* "pywrapfst.pyx":3586
  *                                         increment_subsequential_label))
  *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -37834,18 +38057,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
  * 
  */
   __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, 3542, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_4);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3486
+  /* "pywrapfst.pyx":3530
  * 
  * 
- * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
- *                               float delta=fst.kShortestDelta,
- *                               det_type=b"functional",
+ * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
+ *                              float delta=fst.kShortestDelta,
+ *                              det_type=b"functional",
  */
 
   /* function exit code */
@@ -37867,11 +38090,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_determinize(s
 static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_26determinize[] = "\n  determinize(ifst, delta=1e-6, det_type=\"functional\",\n              nstate=NO_STATE_ID, subsequential_label=0, weight=None,\n              incremental_subsequential_label=False)\n\n  Constructively determinizes a weighted FST.\n\n  This operations creates an equivalent FST that has the property that no\n  state has two transitions with the same input label. For this algorithm,\n  epsilon transitions are treated as regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    det_type: Type of determinization; one of: \"functional\" (input transducer is\n        functional), \"nonfunctional\" (input transducer is not functional) and\n        disambiguate\" (input transducer is not functional but only keep the min\n        of ambiguous outputs).\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n    increment_subsequential_label: Increment subsequential when creating\n        several arcs for the residual final output at a given state.\n\n  Returns:\n    An equivalent deterministic FST.\n\n  Raises:\n    FstArgError: Unknown determinization type.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   PyObject *__pyx_v_det_type = 0;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
-  __pyx_t_10basictypes_int64 __pyx_v_subsequential_label;
+  int64 __pyx_v_nstate;
+  int64 __pyx_v_subsequential_label;
   PyObject *__pyx_v_weight = 0;
   bool __pyx_v_increment_subsequential_label;
   PyObject *__pyx_r = 0;
@@ -37882,11 +38105,11 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[2] = ((PyObject *)__pyx_n_b_functional);
 
-    /* "pywrapfst.pyx":3491
- *                               int64 nstate=fst.kNoStateId,
- *                               int64 subsequential_label=0,
- *                               weight=None,             # <<<<<<<<<<<<<<
- *                               bool increment_subsequential_label=False):
+    /* "pywrapfst.pyx":3535
+ *                              int64 nstate=fst.kNoStateId,
+ *                              int64 subsequential_label=0,
+ *                              weight=None,             # <<<<<<<<<<<<<<
+ *                              bool increment_subsequential_label=False):
  *   """
  */
     values[5] = ((PyObject *)Py_None);
@@ -37954,7 +38177,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, 3486, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3530, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37975,32 +38198,32 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3487, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3531, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__31;
+      __pyx_v_delta = __pyx_k__32;
     }
     __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3489, __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, 3533, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__32;
+      __pyx_v_nstate = __pyx_k__33;
     }
     if (values[4]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3490, __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, 3534, __pyx_L3_error)
     } else {
-      __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
+      __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, 3492, __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, 3536, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3492
- *                               int64 subsequential_label=0,
- *                               weight=None,
- *                               bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3536
+ *                              int64 subsequential_label=0,
+ *                              weight=None,
+ *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
  *   """
  *   determinize(ifst, delta=1e-6, det_type="functional",
  */
@@ -38009,21 +38232,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, 3486, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3530, __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, 3486, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3530, __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":3486
+  /* "pywrapfst.pyx":3530
  * 
  * 
- * cpdef _MutableFst determinize(_Fst ifst,             # <<<<<<<<<<<<<<
- *                               float delta=fst.kShortestDelta,
- *                               det_type=b"functional",
+ * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
+ *                              float delta=fst.kShortestDelta,
+ *                              det_type=b"functional",
  */
 
   /* function exit code */
@@ -38035,7 +38258,7 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label) {
+static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, PyObject *__pyx_v_det_type, int64 __pyx_v_nstate, int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight, bool __pyx_v_increment_subsequential_label) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38049,7 +38272,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, 3486, __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, 3530, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38066,29 +38289,29 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3545
+/* "pywrapfst.pyx":3589
  * 
  * 
- * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                              _Fst ifst2,
- *                              compose_filter=b"auto",
+ * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                             Fst ifst2,
+ *                             compose_filter=b"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) {
+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);
 
-  /* "pywrapfst.pyx":3548
- *                              _Fst ifst2,
- *                              compose_filter=b"auto",
- *                              bool connect=True):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3592
+ *                             Fst ifst2,
+ *                             compose_filter=b"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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
@@ -38103,7 +38326,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
     }
   }
 
-  /* "pywrapfst.pyx":3573
+  /* "pywrapfst.pyx":3617
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -38112,21 +38335,21 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3573, __pyx_L1_error)
+    __PYX_ERR(0, 3617, __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":3577
+  /* "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())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3577, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3577, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":3575
+  /* "pywrapfst.pyx":3619
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
@@ -38135,7 +38358,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3578
+  /* "pywrapfst.pyx":3622
  *       connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -38144,15 +38367,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3578, __pyx_L1_error)
+    __PYX_ERR(0, 3622, __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, 3578, __pyx_L1_error)
+    __PYX_ERR(0, 3622, __pyx_L1_error)
   }
   fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3579
+  /* "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())             # <<<<<<<<<<<<<<
@@ -38160,18 +38383,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
  * 
  */
   __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, 3579, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3545
+  /* "pywrapfst.pyx":3589
  * 
  * 
- * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                              _Fst ifst2,
- *                              compose_filter=b"auto",
+ * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                             Fst ifst2,
+ *                             compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -38189,8 +38412,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_difference(st
 static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_28difference[] = "\n  difference(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively computes the difference of two FSTs.\n\n  This operation computes the difference between two FSAs. Only strings that are\n  in the first automaton but not in second are retained in the result. The first\n  argument must be an acceptor; the second argument must be an unweighted,\n  epsilon-free, deterministic acceptor. The output labels of the first\n  transducer or the input labels of the second transducer must be sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should the output FST be trimmed?\n\n  Returns:\n    An FST representing the difference of the FSTs.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_29difference(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
   PyObject *__pyx_r = 0;
@@ -38224,7 +38447,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, 3545, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3589, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38240,7 +38463,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, 3545, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3589, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38254,17 +38477,17 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
+    __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, 3548, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3592, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3548
- *                              _Fst ifst2,
- *                              compose_filter=b"auto",
- *                              bool connect=True):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3592
+ *                             Fst ifst2,
+ *                             compose_filter=b"auto",
+ *                             bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   difference(ifst1, ifst2, compose_filter="auto", connect=True)
  */
@@ -38273,22 +38496,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, 3545, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3589, __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, 3545, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3546, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_28difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3545
+  /* "pywrapfst.pyx":3589
  * 
  * 
- * cpdef _MutableFst difference(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                              _Fst ifst2,
- *                              compose_filter=b"auto",
+ * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                             Fst ifst2,
+ *                             compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -38300,7 +38523,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38310,7 +38533,7 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   __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, 3545, __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, 3589, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38327,24 +38550,24 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3582
+/* "pywrapfst.pyx":3626
  * 
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kDelta,
- *                                int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kDelta,
+ *                               int64 nstate=fst.kNoStateId,
  */
 
 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__33;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__34;
-  __pyx_t_10basictypes_int64 __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
+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;
+  int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3586
- *                                int64 nstate=fst.kNoStateId,
- *                                int64 subsequential_label=0,
- *                                weight=None):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3630
+ *                               int64 nstate=fst.kNoStateId,
+ *                               int64 subsequential_label=0,
+ *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,
  */
@@ -38352,7 +38575,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
   fst::script::WeightClass __pyx_v_wc;
   std::unique_ptr<fst::script::DisambiguateOptions>  __pyx_v_opts;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -38372,7 +38595,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
     }
   }
 
-  /* "pywrapfst.pyx":3611
+  /* "pywrapfst.pyx":3655
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38381,11 +38604,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3611, __pyx_L1_error)
+    __PYX_ERR(0, 3655, __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":3613
+  /* "pywrapfst.pyx":3657
  *   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(),             # <<<<<<<<<<<<<<
@@ -38394,20 +38617,20 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3613, __pyx_L1_error)
+    __PYX_ERR(0, 3657, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3614
+  /* "pywrapfst.pyx":3658
  *   # 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.DisambiguateOptions] opts
  *   opts.reset(new fst.DisambiguateOptions(delta,
  */
-  __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, 3613, __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, 3657, __pyx_L1_error)
   __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3616
+  /* "pywrapfst.pyx":3660
  *                                                      weight)
  *   cdef unique_ptr[fst.DisambiguateOptions] opts
  *   opts.reset(new fst.DisambiguateOptions(delta,             # <<<<<<<<<<<<<<
@@ -38416,7 +38639,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   __pyx_v_opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label));
 
-  /* "pywrapfst.pyx":3620
+  /* "pywrapfst.pyx":3664
  *                                          nstate,
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -38425,11 +38648,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3620, __pyx_L1_error)
+    __PYX_ERR(0, 3664, __pyx_L1_error)
   }
   fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3621
+  /* "pywrapfst.pyx":3665
  *                                          subsequential_label))
  *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38437,18 +38660,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
  * 
  */
   __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, 3621, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3582
+  /* "pywrapfst.pyx":3626
  * 
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kDelta,
- *                                int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kDelta,
+ *                               int64 nstate=fst.kNoStateId,
  */
 
   /* function exit code */
@@ -38466,10 +38689,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_disambiguate(
 static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_30disambiguate[] = "\n  disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,\n               subsequential_label=0, weight=None):\n\n  Constructively disambiguates a weighted transducer.\n\n  This operation disambiguates a weighted transducer. The result will be an\n  equivalent FST that has the property that no two successful paths have the\n  same input labeling. For this algorithm, epsilon transitions are treated as\n  regular symbols (cf. `rmepsilon`).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    subsequential_label: Input label of arc corresponding to residual final\n        output when producing a subsequential transducer.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An equivalent disambiguated FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
-  __pyx_t_10basictypes_int64 __pyx_v_subsequential_label;
+  int64 __pyx_v_nstate;
+  int64 __pyx_v_subsequential_label;
   PyObject *__pyx_v_weight = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -38478,10 +38701,10 @@ 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":3586
- *                                int64 nstate=fst.kNoStateId,
- *                                int64 subsequential_label=0,
- *                                weight=None):             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":3630
+ *                               int64 nstate=fst.kNoStateId,
+ *                               int64 subsequential_label=0,
+ *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,
  */
@@ -38534,7 +38757,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, 3582, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3626, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38551,41 +38774,41 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3583, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3627, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__33;
+      __pyx_v_delta = __pyx_k__34;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3584, __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, 3628, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__34;
+      __pyx_v_nstate = __pyx_k__35;
     }
     if (values[3]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3585, __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, 3629, __pyx_L3_error)
     } else {
-      __pyx_v_subsequential_label = ((__pyx_t_10basictypes_int64)0);
+      __pyx_v_subsequential_label = ((int64)0);
     }
     __pyx_v_weight = values[4];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3582, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3626, __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, 3582, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3626, __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":3582
+  /* "pywrapfst.pyx":3626
  * 
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kDelta,
- *                                int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kDelta,
+ *                               int64 nstate=fst.kNoStateId,
  */
 
   /* function exit code */
@@ -38597,7 +38820,7 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, __pyx_t_10basictypes_int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight) {
+static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int64 __pyx_v_nstate, int64 __pyx_v_subsequential_label, PyObject *__pyx_v_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38609,7 +38832,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, 3582, __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, 3626, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38626,19 +38849,19 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3624
+/* "pywrapfst.pyx":3668
  * 
  * 
- * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
  *   """
  *   epsnormalize(ifst, eps_norm_output=False)
  */
 
 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) {
+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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   enum fst::EpsNormalizeType __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -38649,7 +38872,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     }
   }
 
-  /* "pywrapfst.pyx":3645
+  /* "pywrapfst.pyx":3689
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -38658,11 +38881,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3645, __pyx_L1_error)
+    __PYX_ERR(0, 3689, __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":3647
+  /* "pywrapfst.pyx":3691
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(
  *       deref(ifst._fst),             # <<<<<<<<<<<<<<
@@ -38671,10 +38894,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3647, __pyx_L1_error)
+    __PYX_ERR(0, 3691, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3649
+  /* "pywrapfst.pyx":3693
  *       deref(ifst._fst),
  *       tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
@@ -38687,7 +38910,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3646
+  /* "pywrapfst.pyx":3690
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(             # <<<<<<<<<<<<<<
@@ -38696,7 +38919,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  */
   fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_t_1);
 
-  /* "pywrapfst.pyx":3650
+  /* "pywrapfst.pyx":3694
  *       tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -38704,16 +38927,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
  * 
  */
   __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, 3650, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3624
+  /* "pywrapfst.pyx":3668
  * 
  * 
- * cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
  *   """
  *   epsnormalize(ifst, eps_norm_output=False)
  */
@@ -38733,7 +38956,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_epsnormalize(
 static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_32epsnormalize[] = "\n  epsnormalize(ifst, eps_norm_output=False)\n\n  Constructively epsilon-normalizes an FST.\n\n  This operation creates an equivalent FST that is epsilon-normalized. An\n  acceptor is epsilon-normalized if it it is epsilon-removed (cf. `rmepsilon`).\n  A transducer is input epsilon-normalized if, in addition, along any path, all\n  arcs with epsilon input labels follow all arcs with non-epsilon input labels.\n  Output epsilon-normalized is defined similarly. The input FST must be\n  functional.\n\n  Args:\n    ifst: The input FST.\n    eps_norm_output: Should the FST be output epsilon-normalized?\n\n  Returns:\n    An equivalent epsilon-normalized FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   bool __pyx_v_eps_norm_output;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -38765,7 +38988,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, 3624, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3668, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38776,22 +38999,22 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3624, __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, 3668, __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, 3624, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3668, __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, 3624, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3668, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_32epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
@@ -38803,7 +39026,7 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output) {
+static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, bool __pyx_v_eps_norm_output) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -38812,7 +39035,7 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   __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, 3624, __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, 3668, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38829,17 +39052,17 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3653
+/* "pywrapfst.pyx":3697
  * 
  * 
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
 
 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__35;
+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;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equal", 0);
@@ -38849,7 +39072,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
     }
   }
 
-  /* "pywrapfst.pyx":3671
+  /* "pywrapfst.pyx":3715
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -38858,19 +39081,19 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3671, __pyx_L1_error)
+    __PYX_ERR(0, 3715, __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, 3671, __pyx_L1_error)
+    __PYX_ERR(0, 3715, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3653
+  /* "pywrapfst.pyx":3697
  * 
  * 
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
@@ -38888,8 +39111,8 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_i
 static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_34equal[] = "\n  equal(ifst1, ifst2, delta=0.0009765625)\n\n  Are two FSTs equal?\n\n  This function tests whether two FSTs have the same states with the same\n  numbering and the same transitions with the same labels and weights in the\n  same order.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the FSTs satisfy the above condition, else False.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_35equal(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -38919,7 +39142,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, 3653, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3697, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38929,7 +39152,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, 3653, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3697, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38941,24 +39164,24 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __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, 3653, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3697, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__35;
+      __pyx_v_delta = __pyx_k__36;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3653, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3697, __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, 3653, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3653, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_34equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -38970,7 +39193,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_34equal(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) {
+static PyObject *__pyx_pf_9pywrapfst_34equal(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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -38981,7 +39204,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   __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, 3653, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3697, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -38998,17 +39221,17 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3674
+/* "pywrapfst.pyx":3718
  * 
  * 
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
 
 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__36;
+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;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equivalent", 0);
@@ -39018,7 +39241,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3692
+  /* "pywrapfst.pyx":3736
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39027,27 +39250,27 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3692, __pyx_L1_error)
+    __PYX_ERR(0, 3736, __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, 3692, __pyx_L1_error)
+    __PYX_ERR(0, 3736, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3674
+  /* "pywrapfst.pyx":3718
  * 
  * 
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst.equivalent", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = -1;
+  __Pyx_WriteUnraisable("pywrapfst.equivalent", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -39057,8 +39280,8 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst__Fst *__py
 static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_36equivalent[] = "\n  equivalent(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors equivalent?\n\n  This operation tests whether two epsilon-free deterministic weighted\n  acceptors are equivalent, that is if they accept the same strings with the\n  same weights.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the FSTs satisfy the above condition, else False.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_37equivalent(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -39088,7 +39311,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, 3674, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3718, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39098,7 +39321,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, 3674, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3718, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39110,24 +39333,24 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __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, 3674, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3718, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__36;
+      __pyx_v_delta = __pyx_k__37;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3674, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3718, __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, 3674, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3674, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_36equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39139,7 +39362,7 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_36equivalent(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) {
+static PyObject *__pyx_pf_9pywrapfst_36equivalent(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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -39149,8 +39372,8 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   __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); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3674, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3674, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39167,29 +39390,29 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3695
+/* "pywrapfst.pyx":3739
  * 
  * 
- * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                             _Fst ifst2,
- *                             compose_filter=b"auto",
+ * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                            Fst ifst2,
+ *                            compose_filter=b"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) {
+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);
 
-  /* "pywrapfst.pyx":3698
- *                             _Fst ifst2,
- *                             compose_filter=b"auto",
- *                             bool connect=True):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3742
+ *                            Fst ifst2,
+ *                            compose_filter=b"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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
@@ -39204,7 +39427,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
     }
   }
 
-  /* "pywrapfst.pyx":3721
+  /* "pywrapfst.pyx":3765
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
@@ -39213,21 +39436,21 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3721, __pyx_L1_error)
+    __PYX_ERR(0, 3765, __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":3725
+  /* "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())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3725, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3725, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":3723
+  /* "pywrapfst.pyx":3767
  *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
  *   cdef unique_ptr[fst.ComposeOptions] opts
  *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
@@ -39236,7 +39459,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3726
+  /* "pywrapfst.pyx":3770
  *       connect,
  *       _get_compose_filter(tostring(compose_filter))))
  *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -39245,15 +39468,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3726, __pyx_L1_error)
+    __PYX_ERR(0, 3770, __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, 3726, __pyx_L1_error)
+    __PYX_ERR(0, 3770, __pyx_L1_error)
   }
   fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3727
+  /* "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())             # <<<<<<<<<<<<<<
@@ -39261,18 +39484,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
  * 
  */
   __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, 3727, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_3);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3695
+  /* "pywrapfst.pyx":3739
  * 
  * 
- * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                             _Fst ifst2,
- *                             compose_filter=b"auto",
+ * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                            Fst ifst2,
+ *                            compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -39290,8 +39513,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_intersect(str
 static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_38intersect[] = "\n  intersect(ifst1, ifst2, compose_filter=\"auto\", connect=True)\n\n  Constructively intersects two FSTs.\n\n  This operation computes the intersection (Hadamard product) of two FSTs.\n  Only strings that are in both automata are retained in the result. The two\n  arguments must be acceptors. One of the arguments must be label-sorted (or\n  otherwise support appropriate matchers).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    compose_filter: A string matching a known composition filter; one of:\n        \"alt_sequence\", \"auto\", \"match\", \"no_match\", \"null\", \"sequence\",\n        \"trivial\".\n    connect: Should output be trimmed?\n\n  Returns:\n    An intersected FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_39intersect(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
   PyObject *__pyx_r = 0;
@@ -39325,7 +39548,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, 3695, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3739, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39341,7 +39564,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, 3695, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3739, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39355,17 +39578,17 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
+    __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, 3698, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3742, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3698
- *                             _Fst ifst2,
- *                             compose_filter=b"auto",
- *                             bool connect=True):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3742
+ *                            Fst ifst2,
+ *                            compose_filter=b"auto",
+ *                            bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   intersect(ifst1, ifst2, compose_filter="auto", connect=True)
  */
@@ -39374,22 +39597,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, 3695, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3739, __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, 3695, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3696, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_38intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3695
+  /* "pywrapfst.pyx":3739
  * 
  * 
- * cpdef _MutableFst intersect(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                             _Fst ifst2,
- *                             compose_filter=b"auto",
+ * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                            Fst ifst2,
+ *                            compose_filter=b"auto",
  */
 
   /* function exit code */
@@ -39401,7 +39624,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
+static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, PyObject *__pyx_v_compose_filter, bool __pyx_v_connect) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -39411,7 +39634,7 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   __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, 3695, __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, 3739, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39428,17 +39651,17 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3730
+/* "pywrapfst.pyx":3774
  * 
  * 
- * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
 
 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__37;
+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;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("isomorphic", 0);
@@ -39448,7 +39671,7 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
     }
   }
 
-  /* "pywrapfst.pyx":3751
+  /* "pywrapfst.pyx":3795
  *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39457,19 +39680,19 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3751, __pyx_L1_error)
+    __PYX_ERR(0, 3795, __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, 3751, __pyx_L1_error)
+    __PYX_ERR(0, 3795, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3730
+  /* "pywrapfst.pyx":3774
  * 
  * 
- * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
@@ -39487,8 +39710,8 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst__Fst *__py
 static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_40isomorphic[] = "\n  isomorphic(ifst1, ifst2, delta=0.0009765625)\n\n  Are the two acceptors isomorphic?\n\n  This operation determines if two transducers with a certain required\n  determinism have the same states, irrespective of numbering, and the same\n  transitions with the same labels and weights, irrespective of ordering. In\n  other words, FSTs A, B are isomorphic if and only if the states of A can be\n  renumbered and the transitions leaving each state reordered so the two are\n  equal (according to the definition given in `equal`).\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    delta: Comparison/quantization delta.\n\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_41isomorphic(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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -39518,7 +39741,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, 3730, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3774, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39528,7 +39751,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, 3730, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3774, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39540,24 +39763,24 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __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, 3730, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3774, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__37;
+      __pyx_v_delta = __pyx_k__38;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3730, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3774, __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, 3730, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3730, __pyx_L1_error)
+  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)
   __pyx_r = __pyx_pf_9pywrapfst_40isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39569,7 +39792,7 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
   return __pyx_r;
 }
 
-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) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -39580,7 +39803,7 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   __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, 3730, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3774, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39597,30 +39820,30 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3754
+/* "pywrapfst.pyx":3798
  * 
  * 
- * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,
  */
 
 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__38;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__39;
+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;
 
-  /* "pywrapfst.pyx":3757
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,
- *                         weight=None):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3801
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,
+ *                        weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
@@ -39637,7 +39860,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
     }
   }
 
-  /* "pywrapfst.pyx":3779
+  /* "pywrapfst.pyx":3823
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -39646,11 +39869,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3779, __pyx_L1_error)
+    __PYX_ERR(0, 3823, __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":3780
+  /* "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)             # <<<<<<<<<<<<<<
@@ -39659,12 +39882,12 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3780, __pyx_L1_error)
+    __PYX_ERR(0, 3824, __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, 3780, __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":3781
+  /* "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)             # <<<<<<<<<<<<<<
@@ -39673,11 +39896,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3781, __pyx_L1_error)
+    __PYX_ERR(0, 3825, __pyx_L1_error)
   }
   fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3782
+  /* "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())             # <<<<<<<<<<<<<<
@@ -39685,18 +39908,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
  * 
  */
   __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, 3782, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_2);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3754
+  /* "pywrapfst.pyx":3798
  * 
  * 
- * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,
  */
 
   /* function exit code */
@@ -39714,9 +39937,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_prune(struct
 static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_42prune[] = "\n  prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)\n\n  Constructively removes paths with weights below a certain threshold.\n\n  This operation deletes states and arcs in the input FST that do not belong\n  to a successful path whose weight is no more (w.r.t the natural semiring\n  order) than the threshold t \\otimes-times the weight of the shortest path in\n  the input FST. Weights must be commutative and have the path property.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold.\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    A pruned FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
+  int64 __pyx_v_nstate;
   PyObject *__pyx_v_weight = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -39725,10 +39948,10 @@ 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":3757
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,
- *                         weight=None):             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":3801
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,
+ *                        weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)
  */
@@ -39773,7 +39996,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, 3754, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3798, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39788,36 +40011,36 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3755, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3799, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__38;
+      __pyx_v_delta = __pyx_k__39;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3756, __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, 3800, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__39;
+      __pyx_v_nstate = __pyx_k__40;
     }
     __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, 3754, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3798, __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, 3754, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3798, __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":3754
+  /* "pywrapfst.pyx":3798
  * 
  * 
- * cpdef _MutableFst prune(_Fst ifst,             # <<<<<<<<<<<<<<
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,
  */
 
   /* function exit code */
@@ -39829,7 +40052,7 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_weight) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -39840,7 +40063,7 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   __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, 3754, __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, 3798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39857,65 +40080,65 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3785
+/* "pywrapfst.pyx":3829
  * 
  * 
- * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
+ * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
  */
 
 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__40;
+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;
 
-  /* "pywrapfst.pyx":3787
- * cpdef _MutableFst push(_Fst ifst,
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,             # <<<<<<<<<<<<<<
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,
+  /* "pywrapfst.pyx":3831
+ * cpdef MutableFst push(Fst ifst,
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,             # <<<<<<<<<<<<<<
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3788
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
- *                        bool push_labels=False,             # <<<<<<<<<<<<<<
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,
+  /* "pywrapfst.pyx":3832
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
+ *                       bool push_labels=False,             # <<<<<<<<<<<<<<
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3789
- *                        bool push_weights=False,
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
- *                        bool remove_total_weight=False,
- *                        bool to_final=False):
+  /* "pywrapfst.pyx":3833
+ *                       bool push_weights=False,
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
+ *                       bool remove_total_weight=False,
+ *                       bool to_final=False):
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3790
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
- *                        bool to_final=False):
+  /* "pywrapfst.pyx":3834
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
+ *                       bool to_final=False):
  *   """
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3791
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,
- *                        bool to_final=False):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3835
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,
+ *                       bool to_final=False):             # <<<<<<<<<<<<<<
  *   """
  *   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;
-  __pyx_t_10basictypes_uint8 __pyx_v_flags;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  uint8 __pyx_v_flags;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("push", 0);
@@ -39940,8 +40163,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3829
- *   # This is copied, almost verbatim, from nlp/fst/bin/fstpush.cc.
+  /* "pywrapfst.pyx":3872
+ *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   cdef uint8 flags = fst.GetPushFlags(push_weights,
@@ -39949,11 +40172,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3829, __pyx_L1_error)
+    __PYX_ERR(0, 3872, __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":3830
+  /* "pywrapfst.pyx":3873
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef uint8 flags = fst.GetPushFlags(push_weights,             # <<<<<<<<<<<<<<
@@ -39962,7 +40185,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   __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":3834
+  /* "pywrapfst.pyx":3877
  *                                       remove_common_affix,
  *                                       remove_total_weight)
  *   fst.Push(deref(ifst._fst),             # <<<<<<<<<<<<<<
@@ -39971,10 +40194,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3834, __pyx_L1_error)
+    __PYX_ERR(0, 3877, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3838
+  /* "pywrapfst.pyx":3881
  *            flags,
  *            fst.GetReweightType(to_final),
  *            delta)             # <<<<<<<<<<<<<<
@@ -39983,7 +40206,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  */
   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":3839
+  /* "pywrapfst.pyx":3882
  *            fst.GetReweightType(to_final),
  *            delta)
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -39991,18 +40214,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
  * 
  */
   __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, 3839, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3785
+  /* "pywrapfst.pyx":3829
  * 
  * 
- * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
+ * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
  */
 
   /* function exit code */
@@ -40020,7 +40243,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_push(struct _
 static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_44push[] = "\n  push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,\n       remove_common_affix=False, remove_total_weight=False, to_final=False)\n\n  Constructively pushes weights/labels towards initial or final states.\n\n  This operation produces an equivalent transducer by pushing the weights\n  and/or the labels towards the initial state or toward the final states.\n\n  When pushing weights towards the initial state, the sum of the weight of the\n  outgoing transitions and final weight at any non-initial state is equal to 1\n  in the resulting machine. When pushing weights towards the final states, the\n  sum of the weight of the incoming transitions at any state is equal to 1.\n  Weights need to be left distributive when pushing towards the initial state\n  and right distributive when pushing towards the final states.\n\n  Pushing labels towards the initial state consists in minimizing at every\n  state the length of the longest common prefix of the output labels of the\n  outgoing paths. Pushing labels towards the final states consists in\n  minimizing at every state the length of the longest common suffix of the\n  output labels of the incoming paths.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    push_weights: Should weights be pushed?\n    push_labels: Should labels be pushed?\n    remove_common_affix: If pushing labels, should common prefix/suffix be\n        removed?\n    remove_total_weight: If pushing weights, should total weight be removed?\n    to_final: Push towards final states?\n\n  Returns:\n    An equivalent pushed FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   bool __pyx_v_push_weights;
   bool __pyx_v_push_labels;
@@ -40097,7 +40320,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, 3785, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3829, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40118,72 +40341,72 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 3786, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3830, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__40;
+      __pyx_v_delta = __pyx_k__41;
     }
     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, 3787, __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, 3831, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3787
- * cpdef _MutableFst push(_Fst ifst,
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,             # <<<<<<<<<<<<<<
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,
+      /* "pywrapfst.pyx":3831
+ * cpdef MutableFst push(Fst ifst,
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,             # <<<<<<<<<<<<<<
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,
  */
       __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, 3788, __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, 3832, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3788
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
- *                        bool push_labels=False,             # <<<<<<<<<<<<<<
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,
+      /* "pywrapfst.pyx":3832
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
+ *                       bool push_labels=False,             # <<<<<<<<<<<<<<
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,
  */
       __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, 3789, __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, 3833, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3789
- *                        bool push_weights=False,
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,             # <<<<<<<<<<<<<<
- *                        bool remove_total_weight=False,
- *                        bool to_final=False):
+      /* "pywrapfst.pyx":3833
+ *                       bool push_weights=False,
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
+ *                       bool remove_total_weight=False,
+ *                       bool to_final=False):
  */
       __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, 3790, __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, 3834, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3790
- *                        bool push_labels=False,
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,             # <<<<<<<<<<<<<<
- *                        bool to_final=False):
+      /* "pywrapfst.pyx":3834
+ *                       bool push_labels=False,
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
+ *                       bool to_final=False):
  *   """
  */
       __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, 3791, __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, 3835, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3791
- *                        bool remove_common_affix=False,
- *                        bool remove_total_weight=False,
- *                        bool to_final=False):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3835
+ *                       bool remove_common_affix=False,
+ *                       bool remove_total_weight=False,
+ *                       bool to_final=False):             # <<<<<<<<<<<<<<
  *   """
  *   push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,
  */
@@ -40192,21 +40415,21 @@ 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, 3785, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3829, __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, 3785, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3829, __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":3785
+  /* "pywrapfst.pyx":3829
  * 
  * 
- * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
+ * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
  */
 
   /* function exit code */
@@ -40218,7 +40441,7 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
   return __pyx_r;
 }
 
-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) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -40232,7 +40455,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, 3785, __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, 3829, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40249,21 +40472,21 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3842
+/* "pywrapfst.pyx":3885
  * 
  * 
- * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
+ * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                           Fst ifst2,
  *                           int32 npath=1,
  */
 
 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) {
-  __pyx_t_10basictypes_int32 __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
-  float __pyx_v_delta = __pyx_k__41;
+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);
-  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__42;
+  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;
   bool __pyx_r;
@@ -40290,18 +40513,18 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
     }
   }
 
-  /* "pywrapfst.pyx":3875
+  /* "pywrapfst.pyx":3918
  *     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
  *   # 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, 3875, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3875, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":3878
+  /* "pywrapfst.pyx":3921
  *   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,             # <<<<<<<<<<<<<<
@@ -40310,7 +40533,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, 1, 0, 0));
 
-  /* "pywrapfst.pyx":3883
+  /* "pywrapfst.pyx":3926
  *                                                           False,
  *                                                           False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40320,7 +40543,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3884
+    /* "pywrapfst.pyx":3927
  *                                                           False))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -40329,7 +40552,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3883
+    /* "pywrapfst.pyx":3926
  *                                                           False,
  *                                                           False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40338,7 +40561,7 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   }
 
-  /* "pywrapfst.pyx":3885
+  /* "pywrapfst.pyx":3928
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -40347,10 +40570,10 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3885, __pyx_L1_error)
+    __PYX_ERR(0, 3928, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3886
+  /* "pywrapfst.pyx":3929
  *     seed = time(NULL) + getpid()
  *   return fst.RandEquivalent(deref(ifst1._fst),
  *                             deref(ifst2._fst),             # <<<<<<<<<<<<<<
@@ -40359,10 +40582,10 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3886, __pyx_L1_error)
+    __PYX_ERR(0, 3929, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3885
+  /* "pywrapfst.pyx":3928
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
@@ -40372,11 +40595,11 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
   __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));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3842
+  /* "pywrapfst.pyx":3885
  * 
  * 
- * cpdef bool randequivalent(_Fst ifst1,             # <<<<<<<<<<<<<<
- *                           _Fst ifst2,
+ * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
+ *                           Fst ifst2,
  *                           int32 npath=1,
  */
 
@@ -40393,13 +40616,13 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst__Fst *
 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 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;
-  __pyx_t_10basictypes_int32 __pyx_v_npath;
+  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;
-  __pyx_t_10basictypes_int32 __pyx_v_max_length;
+  int32 __pyx_v_max_length;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("randequivalent (wrapper)", 0);
@@ -40437,7 +40660,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, 3842, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3885, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -40471,7 +40694,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3842, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3885, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40491,40 +40714,40 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
-    __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3844, __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, 3887, __pyx_L3_error)
     } else {
-      __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
+      __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, 3845, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3888, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__41;
+      __pyx_v_delta = __pyx_k__42;
     }
     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, 3846, __pyx_L3_error)
+      __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)
     } else {
       __pyx_v_seed = ((time_t)0);
     }
     __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3848, __pyx_L3_error)
+      __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)
     } else {
-      __pyx_v_max_length = __pyx_k__42;
+      __pyx_v_max_length = __pyx_k__43;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3842, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3885, __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, 3842, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst__Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3843, __pyx_L1_error)
+  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);
 
   /* function exit code */
@@ -40536,7 +40759,7 @@ 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, __pyx_t_10basictypes_int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_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, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
@@ -40550,8 +40773,8 @@ static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__
   __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, 3842, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3842, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -40568,34 +40791,34 @@ static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3893
+/* "pywrapfst.pyx":3936
  * 
  * 
- * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
- *                           int32 npath=1,
- *                           time_t seed=0,
+ * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
+ *                          int32 npath=1,
+ *                          time_t seed=0,
  */
 
 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) {
-  __pyx_t_10basictypes_int32 __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
+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);
-  __pyx_t_10basictypes_int32 __pyx_v_max_length = __pyx_k__43;
+  int32 __pyx_v_max_length = __pyx_k__44;
 
-  /* "pywrapfst.pyx":3898
- *                           select=b"uniform",
- *                           int32 max_length=INT32_MAX,
- *                           bool weighted=False,             # <<<<<<<<<<<<<<
- *                           bool remove_total_weight=False):
+  /* "pywrapfst.pyx":3941
+ *                          select=b"uniform",
+ *                          int32 max_length=INT32_MAX,
+ *                          bool weighted=False,             # <<<<<<<<<<<<<<
+ *                          bool remove_total_weight=False):
  *   """
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3899
- *                           int32 max_length=INT32_MAX,
- *                           bool weighted=False,
- *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3942
+ *                          int32 max_length=INT32_MAX,
+ *                          bool weighted=False,
+ *                          bool remove_total_weight=False):             # <<<<<<<<<<<<<<
  *   """
  *   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
  */
@@ -40603,7 +40826,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
   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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::script::RandArcSelection __pyx_t_2;
@@ -40631,18 +40854,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
     }
   }
 
-  /* "pywrapfst.pyx":3929
+  /* "pywrapfst.pyx":3972
  *     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, 3929, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3929, __pyx_L1_error)
+  __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":3931
+  /* "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,             # <<<<<<<<<<<<<<
@@ -40651,7 +40874,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   __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":3937
+  /* "pywrapfst.pyx":3980
  *                                                           remove_total_weight))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -40660,11 +40883,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3937, __pyx_L1_error)
+    __PYX_ERR(0, 3980, __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":3938
+  /* "pywrapfst.pyx":3981
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40674,7 +40897,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3939
+    /* "pywrapfst.pyx":3982
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:
  *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
@@ -40683,7 +40906,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
     __pyx_v_seed = (time(NULL) + getpid());
 
-    /* "pywrapfst.pyx":3938
+    /* "pywrapfst.pyx":3981
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
@@ -40692,7 +40915,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   }
 
-  /* "pywrapfst.pyx":3940
+  /* "pywrapfst.pyx":3983
  *   if seed == 0:
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))             # <<<<<<<<<<<<<<
@@ -40701,11 +40924,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3940, __pyx_L1_error)
+    __PYX_ERR(0, 3983, __pyx_L1_error)
   }
   fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_seed, (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3941
+  /* "pywrapfst.pyx":3984
  *     seed = time(NULL) + getpid()
  *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -40713,18 +40936,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
  * 
  */
   __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, 3941, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_4);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3893
+  /* "pywrapfst.pyx":3936
  * 
  * 
- * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
- *                           int32 npath=1,
- *                           time_t seed=0,
+ * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
+ *                          int32 npath=1,
+ *                          time_t seed=0,
  */
 
   /* function exit code */
@@ -40742,11 +40965,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_randgen(struc
 static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_48randgen[] = "\n  randgen(ifst, npath=1, seed=0, select=\"uniform\", max_length=2147483647,\n          weighted=False, remove_total_weight=False)\n\n  Randomly generate successful paths in an FST.\n\n  This operation randomly generates a set of successful paths in the input FST.\n  This relies on a mechanism for selecting arcs, specified using the `select`\n  argument. The default selector, \"uniform\", randomly selects a transition\n  using a uniform distribution. The \"log_prob\" selector randomly selects a\n  transition w.r.t. the weights treated as negative log probabilities after\n  normalizing for the total weight leaving the state. In all cases, finality is\n  treated as a transition to a super-final state.\n\n  Args:\n    ifst: The input FST.\n    npath: The number of random paths to generate.\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    weighted: Should the output be weighted by path count?\n    remove_total_weight: Should the total weight be removed (ignored when\n        `weighted` is False)?\n\n  Returns:\n    An FST containing one or more random paths.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
-  __pyx_t_10basictypes_int32 __pyx_v_npath;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
+  int32 __pyx_v_npath;
   time_t __pyx_v_seed;
   PyObject *__pyx_v_select = 0;
-  __pyx_t_10basictypes_int32 __pyx_v_max_length;
+  int32 __pyx_v_max_length;
   bool __pyx_v_weighted;
   bool __pyx_v_remove_total_weight;
   PyObject *__pyx_r = 0;
@@ -40820,7 +41043,7 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3893, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3936, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40841,44 +41064,44 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3894, __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, 3937, __pyx_L3_error)
     } else {
-      __pyx_v_npath = ((__pyx_t_10basictypes_int32)1);
+      __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, 3895, __pyx_L3_error)
+      __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)
     } else {
       __pyx_v_seed = ((time_t)0);
     }
     __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3897, __pyx_L3_error)
+      __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__43;
+      __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, 3898, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3941, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3898
- *                           select=b"uniform",
- *                           int32 max_length=INT32_MAX,
- *                           bool weighted=False,             # <<<<<<<<<<<<<<
- *                           bool remove_total_weight=False):
+      /* "pywrapfst.pyx":3941
+ *                          select=b"uniform",
+ *                          int32 max_length=INT32_MAX,
+ *                          bool weighted=False,             # <<<<<<<<<<<<<<
+ *                          bool remove_total_weight=False):
  *   """
  */
       __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, 3899, __pyx_L3_error)
+      __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)
     } else {
 
-      /* "pywrapfst.pyx":3899
- *                           int32 max_length=INT32_MAX,
- *                           bool weighted=False,
- *                           bool remove_total_weight=False):             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":3942
+ *                          int32 max_length=INT32_MAX,
+ *                          bool weighted=False,
+ *                          bool remove_total_weight=False):             # <<<<<<<<<<<<<<
  *   """
  *   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
  */
@@ -40887,21 +41110,21 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3893, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3936, __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, 3893, __pyx_L1_error)
+  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);
 
-  /* "pywrapfst.pyx":3893
+  /* "pywrapfst.pyx":3936
  * 
  * 
- * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
- *                           int32 npath=1,
- *                           time_t seed=0,
+ * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
+ *                          int32 npath=1,
+ *                          time_t seed=0,
  */
 
   /* function exit code */
@@ -40913,7 +41136,7 @@ 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, __pyx_t_10basictypes_int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, __pyx_t_10basictypes_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, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -40927,7 +41150,7 @@ static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_sel
   __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, 3893, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40944,36 +41167,36 @@ static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3944
+/* "pywrapfst.pyx":3987
  * 
  * 
- * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                           call_arc_labeling=b"input",
- *                           return_arc_labeling=b"neither",
+ * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
+ *                          call_arc_labeling=b"input",
+ *                          return_arc_labeling=b"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) {
+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);
 
-  /* "pywrapfst.pyx":3947
- *                           call_arc_labeling=b"input",
- *                           return_arc_labeling=b"neither",
- *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
- *                           int64 return_label=0):
+  /* "pywrapfst.pyx":3990
+ *                          call_arc_labeling=b"input",
+ *                          return_arc_labeling=b"neither",
+ *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
+ *                          int64 return_label=0):
  *   """
  */
   bool __pyx_v_epsilon_on_replace = ((bool)0);
-  __pyx_t_10basictypes_int64 __pyx_v_return_label = ((__pyx_t_10basictypes_int64)0);
-  std::vector<__pyx_t_3fst_LabelFstClassPair>  __pyx_v__pairs;
-  __pyx_t_10basictypes_int64 __pyx_v_label;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_pfst = 0;
+  int64 __pyx_v_return_label = ((int64)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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   Py_ssize_t __pyx_t_2;
@@ -40983,8 +41206,8 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   PyObject *(*__pyx_t_8)(PyObject *);
-  __pyx_t_10basictypes_int64 __pyx_t_9;
-  __pyx_t_3fst_LabelFstClassPair __pyx_t_10;
+  int64 __pyx_t_9;
+  __pyx_t_10cpywrapfst_LabelFstClassPair __pyx_t_10;
   std::string __pyx_t_11;
   enum fst::ReplaceLabelType __pyx_t_12;
   __Pyx_RefNannySetupContext("replace", 0);
@@ -41003,9 +41226,9 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     }
   }
 
-  /* "pywrapfst.pyx":3988
+  /* "pywrapfst.pyx":4031
  *   cdef int64 label
- *   cdef _Fst pfst
+ *   cdef Fst pfst
  *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
  *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
@@ -41014,26 +41237,26 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
     __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, 3988, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3988, __pyx_L1_error)
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4031, __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, 3988, __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, 4031, __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, 3988, __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, 4031, __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, 3988, __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, 4031, __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, 3988, __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, 4031, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
@@ -41043,7 +41266,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 3988, __pyx_L1_error)
+          else __PYX_ERR(0, 4031, __pyx_L1_error)
         }
         break;
       }
@@ -41055,7 +41278,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        __PYX_ERR(0, 3988, __pyx_L1_error)
+        __PYX_ERR(0, 4031, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -41068,15 +41291,15 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __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, 3988, __pyx_L1_error)
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4031, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3988, __pyx_L1_error)
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4031, __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, 3988, __pyx_L1_error)
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4031, __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;
@@ -41084,7 +41307,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __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, 3988, __pyx_L1_error)
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 4031, __pyx_L1_error)
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L6_unpacking_done;
@@ -41092,18 +41315,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      __PYX_ERR(0, 3988, __pyx_L1_error)
+      __PYX_ERR(0, 4031, __pyx_L1_error)
       __pyx_L6_unpacking_done:;
     }
-    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3988, __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, 4031, __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, 3988, __pyx_L1_error)
+    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));
+    __Pyx_XDECREF_SET(__pyx_v_pfst, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_6));
     __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":3989
- *   cdef _Fst pfst
+    /* "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
@@ -41111,24 +41334,24 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
     if (unlikely(((PyObject *)__pyx_v_pfst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 3989, __pyx_L1_error)
+      __PYX_ERR(0, 4032, __pyx_L1_error)
     }
     try {
-      __pyx_t_10 = __pyx_t_3fst_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, 3989, __pyx_L1_error)
+      __PYX_ERR(0, 4032, __pyx_L1_error)
     }
     try {
       __pyx_v__pairs.push_back(__pyx_t_10);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 3989, __pyx_L1_error)
+      __PYX_ERR(0, 4032, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":3988
+    /* "pywrapfst.pyx":4031
  *   cdef int64 label
- *   cdef _Fst pfst
+ *   cdef Fst pfst
  *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
  *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
  *   cdef unique_ptr[fst.VectorFstClass] tfst
@@ -41136,7 +41359,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3991
+  /* "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()))             # <<<<<<<<<<<<<<
@@ -41145,45 +41368,45 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   __pyx_v_tfst.reset(new fst::script::VectorFstClass((__pyx_v__pairs[0]).second->ArcType()));
 
-  /* "pywrapfst.pyx":3993
+  /* "pywrapfst.pyx":4036
  *   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(
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3993, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4036, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3992
+  /* "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(             # <<<<<<<<<<<<<<
  *       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, 3992, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":3996
+  /* "pywrapfst.pyx":4039
  *       epsilon_on_replace)
  *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
  *       tostring(return_arc_labeling),             # <<<<<<<<<<<<<<
  *       epsilon_on_replace)
  *   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, 3996, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4039, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3995
+  /* "pywrapfst.pyx":4038
  *       tostring(call_arc_labeling),
  *       epsilon_on_replace)
  *   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, 3995, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":3999
+  /* "pywrapfst.pyx":4042
  *       epsilon_on_replace)
  *   cdef unique_ptr[fst.ReplaceOptions] opts
  *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))             # <<<<<<<<<<<<<<
@@ -41192,7 +41415,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   __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":4000
+  /* "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))             # <<<<<<<<<<<<<<
@@ -41201,7 +41424,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  */
   fst::script::Replace(__pyx_v__pairs, __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":4001
+  /* "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())             # <<<<<<<<<<<<<<
@@ -41209,18 +41432,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_replace(PyObj
  * 
  */
   __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, 4001, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3944
+  /* "pywrapfst.pyx":3987
  * 
  * 
- * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                           call_arc_labeling=b"input",
- *                           return_arc_labeling=b"neither",
+ * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
+ *                          call_arc_labeling=b"input",
+ *                          return_arc_labeling=b"neither",
  */
 
   /* function exit code */
@@ -41247,7 +41470,7 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
   PyObject *__pyx_v_call_arc_labeling = 0;
   PyObject *__pyx_v_return_arc_labeling = 0;
   bool __pyx_v_epsilon_on_replace;
-  __pyx_t_10basictypes_int64 __pyx_v_return_label;
+  int64 __pyx_v_return_label;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("replace (wrapper)", 0);
@@ -41304,7 +41527,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, 3944, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3987, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41325,27 +41548,27 @@ 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, 3947, __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, 3990, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3947
- *                           call_arc_labeling=b"input",
- *                           return_arc_labeling=b"neither",
- *                           bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
- *                           int64 return_label=0):
+      /* "pywrapfst.pyx":3990
+ *                          call_arc_labeling=b"input",
+ *                          return_arc_labeling=b"neither",
+ *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
+ *                          int64 return_label=0):
  *   """
  */
       __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_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3948, __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, 3991, __pyx_L3_error)
     } else {
-      __pyx_v_return_label = ((__pyx_t_10basictypes_int64)0);
+      __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, 3944, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3987, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -41353,12 +41576,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":3944
+  /* "pywrapfst.pyx":3987
  * 
  * 
- * cpdef _MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                           call_arc_labeling=b"input",
- *                           return_arc_labeling=b"neither",
+ * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
+ *                          call_arc_labeling=b"input",
+ *                          return_arc_labeling=b"neither",
  */
 
   /* function exit code */
@@ -41366,7 +41589,7 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-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, __pyx_t_10basictypes_int64 __pyx_v_return_label) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -41378,7 +41601,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, 3944, __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, 3987, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41395,19 +41618,19 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4004
+/* "pywrapfst.pyx":4047
  * 
  * 
- * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
  *   """
  *   reverse(ifst, require_superinitial=True)
  */
 
 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) {
+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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("reverse", 0);
@@ -41417,7 +41640,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
     }
   }
 
-  /* "pywrapfst.pyx":4024
+  /* "pywrapfst.pyx":4067
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -41426,11 +41649,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4024, __pyx_L1_error)
+    __PYX_ERR(0, 4067, __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":4025
+  /* "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)             # <<<<<<<<<<<<<<
@@ -41439,11 +41662,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4025, __pyx_L1_error)
+    __PYX_ERR(0, 4068, __pyx_L1_error)
   }
   fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":4026
+  /* "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())             # <<<<<<<<<<<<<<
@@ -41451,16 +41674,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
  * 
  */
   __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, 4026, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4004
+  /* "pywrapfst.pyx":4047
  * 
  * 
- * cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
  *   """
  *   reverse(ifst, require_superinitial=True)
  */
@@ -41480,7 +41703,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_reverse(struc
 static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_52reverse[] = "\n  reverse(ifst, require_superinitial=True)\n\n  Constructively reverses an FST's transduction.\n\n  This operation reverses an FST. If A transduces string x to y with weight a,\n  then the reverse of A transduces the reverse of x to the reverse of y with\n  weight a.Reverse(). (Typically, a = a.Reverse() and Arc = RevArc, e.g.,\n  TropicalWeight and LogWeight.) In general, e.g., when the weights only form a\n  left or right semiring, the output arc type must match the input arc type.\n\n  Args:\n    ifst: The input FST.\n    require_superinitial: Should a superinitial state be created?\n\n  Returns:\n    A reversed FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   bool __pyx_v_require_superinitial;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -41512,7 +41735,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, 4004, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4047, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41523,22 +41746,22 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 4004, __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, 4047, __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, 4004, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4047, __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, 4004, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4047, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_52reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
@@ -41550,7 +41773,7 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial) {
+static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -41559,7 +41782,7 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   __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, 4004, __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, 4047, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41576,20 +41799,20 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4032
+/* "pywrapfst.pyx":4075
  * 
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                                                 float delta=fst.kShortestDelta,
  *                                                 int64 nstate=fst.kNoStateId,
  */
 
-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__44;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__45;
+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);
 
-  /* "pywrapfst.pyx":4036
+  /* "pywrapfst.pyx":4079
  *                                                 int64 nstate=fst.kNoStateId,
  *                                                 queue_type=b"auto",
  *                                                 bool reverse=False) except *:             # <<<<<<<<<<<<<<
@@ -41621,7 +41844,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     }
   }
 
-  /* "pywrapfst.pyx":4038
+  /* "pywrapfst.pyx":4081
  *                                                 bool reverse=False) except *:
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
@@ -41632,11 +41855,11 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 4038, __pyx_L1_error)
+    __PYX_ERR(0, 4081, __pyx_L1_error)
   }
   __pyx_v_distance.reset(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4042
+  /* "pywrapfst.pyx":4085
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -41646,7 +41869,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_t_2 = (__pyx_v_reverse != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":4045
+    /* "pywrapfst.pyx":4088
  *     # 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)             # <<<<<<<<<<<<<<
@@ -41655,11 +41878,11 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4045, __pyx_L1_error)
+      __PYX_ERR(0, 4088, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":4042
+    /* "pywrapfst.pyx":4085
  *   # not be used in all cases.
  *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
  *   if reverse:             # <<<<<<<<<<<<<<
@@ -41669,7 +41892,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":4047
+  /* "pywrapfst.pyx":4090
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -41678,17 +41901,17 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":4048
+    /* "pywrapfst.pyx":4091
  *   else:
  *     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, 4048, __pyx_L1_error)
-    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4048, __pyx_L1_error)
+    __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)
 
-    /* "pywrapfst.pyx":4047
+    /* "pywrapfst.pyx":4090
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
  *   else:
  *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
@@ -41697,7 +41920,7 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     __pyx_v_opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_4, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
 
-    /* "pywrapfst.pyx":4052
+    /* "pywrapfst.pyx":4095
  *         nstate,
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -41706,13 +41929,13 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4052, __pyx_L1_error)
+      __PYX_ERR(0, 4095, __pyx_L1_error)
     }
     fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), (*__pyx_v_opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":4053
+  /* "pywrapfst.pyx":4096
  *         delta))
  *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
  *   return distance.release()             # <<<<<<<<<<<<<<
@@ -41722,10 +41945,10 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   __pyx_r = __pyx_v_distance.release();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4032
+  /* "pywrapfst.pyx":4075
  * 
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                                                 float delta=fst.kShortestDelta,
  *                                                 int64 nstate=fst.kNoStateId,
  */
@@ -41739,10 +41962,10 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4056
+/* "pywrapfst.pyx":4099
  * 
  * 
- * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
@@ -41752,9 +41975,9 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
 static char __pyx_doc_9pywrapfst_54shortestdistance[] = "\n  shortestdistance(ifst, delta=1e-6, nstate=NO_STATE_ID,\n                   queue_type=\"auto\", reverse=False)\n\n  Compute the shortest distance from the initial or final state.\n\n  This operation computes the shortest distance from the initial state (when\n  `reverse` is False) or from every state to the final state (when `reverse` is\n  True). The shortest distance from p to q is the \\otimes-sum of the weights of\n  all the paths between p and q. The weights must be right (if `reverse` is\n  False) or left (if `reverse` is True) distributive, and k-closed (i.e., 1\n  \\otimes x \\otimes x^2 \\otimes ... \\otimes x^{k + 1} = 1 \\otimes x \\otimes x^2\n  \\otimes ... \\otimes x^k; e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nstate: State number threshold (ignored if `reverse` is True).\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\" (ignored if `reverse` is True).\n    reverse: Should the reverse distance (from each state to the final state)\n        be computed?\n\n  Returns:\n    A list of Weight objects representing the shortest distance for each state.\n  ";
 static PyMethodDef __pyx_mdef_9pywrapfst_55shortestdistance = {"shortestdistance", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_55shortestdistance, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_54shortestdistance};
 static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
+  int64 __pyx_v_nstate;
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_reverse;
   PyObject *__pyx_r = 0;
@@ -41812,7 +42035,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, 4056, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4099, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41829,23 +42052,23 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 4057, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4100, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__46;
+      __pyx_v_delta = __pyx_k__47;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4058, __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, 4101, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__47;
+      __pyx_v_nstate = __pyx_k__48;
     }
     __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, 4060, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4103, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4060
+      /* "pywrapfst.pyx":4103
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
@@ -41857,19 +42080,19 @@ 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, 4056, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4099, __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, 4056, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4099, __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":4056
+  /* "pywrapfst.pyx":4099
  * 
  * 
- * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
@@ -41883,7 +42106,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse) {
+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;
   fst::script::WeightClass __pyx_7genexpr__pyx_v_weight;
@@ -41899,7 +42122,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":4088
+  /* "pywrapfst.pyx":4131
  *   """
  *   cdef unique_ptr[vector[fst.WeightClass]] distance
  *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))             # <<<<<<<<<<<<<<
@@ -41911,10 +42134,10 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   __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, 4088, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":4089
+  /* "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()             # <<<<<<<<<<<<<<
@@ -41923,11 +42146,11 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4089, __pyx_L1_error)
+    __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_v_weight_type = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0);
 
-  /* "pywrapfst.pyx":4090
+  /* "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)]             # <<<<<<<<<<<<<<
@@ -41936,7 +42159,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
  */
   __Pyx_XDECREF(__pyx_r);
   { /* enter inner scope */
-    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4090, __pyx_L1_error)
+    __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();
@@ -41945,11 +42168,11 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
       __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, 4090, __pyx_L1_error)
+      __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)
       __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, 4090, __pyx_L1_error)
+      __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_GOTREF(__pyx_t_7);
-      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4090, __pyx_L1_error)
+      __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_6);
       PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
@@ -41957,10 +42180,10 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
       PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_7);
       __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, 4090, __pyx_L1_error)
+      __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, 4090, __pyx_L1_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4133, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
   } /* exit inner scope */
@@ -41968,10 +42191,10 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4056
+  /* "pywrapfst.pyx":4099
  * 
  * 
- * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
@@ -41990,34 +42213,34 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4093
+/* "pywrapfst.pyx":4136
  * 
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kShortestDelta,
- *                                int32 nshortest=1,
+ * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kShortestDelta,
+ *                               int32 nshortest=1,
  */
 
 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__48;
-  __pyx_t_10basictypes_int32 __pyx_v_nshortest = ((__pyx_t_10basictypes_int32)1);
-  __pyx_t_10basictypes_int64 __pyx_v_nstate = __pyx_k__49;
+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;
+  int32 __pyx_v_nshortest = ((int32)1);
+  int64 __pyx_v_nstate = __pyx_k__50;
   PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
 
-  /* "pywrapfst.pyx":4098
- *                                int64 nstate=fst.kNoStateId,
- *                                queue_type=b"auto",
- *                                bool unique=False,             # <<<<<<<<<<<<<<
- *                                weight=None):
+  /* "pywrapfst.pyx":4141
+ *                               int64 nstate=fst.kNoStateId,
+ *                               queue_type=b"auto",
+ *                               bool unique=False,             # <<<<<<<<<<<<<<
+ *                               weight=None):
  *   """
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4099
- *                                queue_type=b"auto",
- *                                bool unique=False,
- *                                weight=None):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4142
+ *                               queue_type=b"auto",
+ *                               bool unique=False,
+ *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,
  */
@@ -42025,7 +42248,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
   std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
   fst::script::WeightClass __pyx_v_wc;
   std::unique_ptr<fst::script::ShortestPathOptions>  __pyx_v_opts;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   std::string __pyx_t_2;
@@ -42053,7 +42276,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
     }
   }
 
-  /* "pywrapfst.pyx":4131
+  /* "pywrapfst.pyx":4174
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -42062,11 +42285,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4131, __pyx_L1_error)
+    __PYX_ERR(0, 4174, __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":4133
+  /* "pywrapfst.pyx":4176
  *   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)             # <<<<<<<<<<<<<<
@@ -42075,22 +42298,22 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4133, __pyx_L1_error)
+    __PYX_ERR(0, 4176, __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, 4133, __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":4135
+  /* "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,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4135, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4135, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":4140
+  /* "pywrapfst.pyx":4183
  *                                          delta,
  *                                          wc,
  *                                          nstate))             # <<<<<<<<<<<<<<
@@ -42099,7 +42322,7 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   __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));
 
-  /* "pywrapfst.pyx":4141
+  /* "pywrapfst.pyx":4184
  *                                          wc,
  *                                          nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
@@ -42108,11 +42331,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4141, __pyx_L1_error)
+    __PYX_ERR(0, 4184, __pyx_L1_error)
   }
   fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":4142
+  /* "pywrapfst.pyx":4185
  *                                          nstate))
  *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -42120,18 +42343,18 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
  * 
  */
   __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, 4142, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_4);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4093
+  /* "pywrapfst.pyx":4136
  * 
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kShortestDelta,
- *                                int32 nshortest=1,
+ * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kShortestDelta,
+ *                               int32 nshortest=1,
  */
 
   /* function exit code */
@@ -42149,10 +42372,10 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_shortestpath(
 static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_56shortestpath[] = "\n  shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,\n               queue_type=\"auto\", unique=False, weight=None)\n\n  Construct an FST containing the shortest path(s) in the input FST.\n\n  This operation produces an FST containing the n-shortest paths in the input\n  FST. The n-shortest paths are the n-lowest weight paths w.r.t. the natural\n  semiring order. The single path that can be read from the ith of at most n\n  transitions leaving the initial state of the resulting FST is the ith\n  shortest path. The weights need to be right distributive and have the path\n  property. They also need to be left distributive as well for n-shortest with\n  n > 1 (e.g., TropicalWeight).\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta.\n    nshortest: The number of paths to return.\n    nstate: State number threshold.\n    queue_type: A string matching a known queue type; one of: \"auto\", \"fifo\",\n        \"lifo\", \"shortest\", \"state\", \"top\".\n    unique: Should the resulting FST only contain distinct paths? (Requires\n        the input FST to be an acceptor; epsilons are treated as if they are\n        regular symbols.)\n    weight: A Weight or weight string indicating the desired weight threshold\n        below which paths are pruned; if omitted, no paths are pruned.\n\n  Returns:\n    An FST containing the n-shortest paths.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
-  __pyx_t_10basictypes_int32 __pyx_v_nshortest;
-  __pyx_t_10basictypes_int64 __pyx_v_nstate;
+  int32 __pyx_v_nshortest;
+  int64 __pyx_v_nstate;
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_unique;
   PyObject *__pyx_v_weight = 0;
@@ -42164,10 +42387,10 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
     PyObject* values[7] = {0,0,0,0,0,0,0};
     values[4] = ((PyObject *)__pyx_n_b_auto);
 
-    /* "pywrapfst.pyx":4099
- *                                queue_type=b"auto",
- *                                bool unique=False,
- *                                weight=None):             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":4142
+ *                               queue_type=b"auto",
+ *                               bool unique=False,
+ *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,
  */
@@ -42236,7 +42459,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, 4093, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4136, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42257,32 +42480,32 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __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, 4094, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4137, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__48;
+      __pyx_v_delta = __pyx_k__49;
     }
     if (values[2]) {
-      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4095, __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, 4138, __pyx_L3_error)
     } else {
-      __pyx_v_nshortest = ((__pyx_t_10basictypes_int32)1);
+      __pyx_v_nshortest = ((int32)1);
     }
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4096, __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, 4139, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__49;
+      __pyx_v_nstate = __pyx_k__50;
     }
     __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, 4098, __pyx_L3_error)
+      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4141, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4098
- *                                int64 nstate=fst.kNoStateId,
- *                                queue_type=b"auto",
- *                                bool unique=False,             # <<<<<<<<<<<<<<
- *                                weight=None):
+      /* "pywrapfst.pyx":4141
+ *                               int64 nstate=fst.kNoStateId,
+ *                               queue_type=b"auto",
+ *                               bool unique=False,             # <<<<<<<<<<<<<<
+ *                               weight=None):
  *   """
  */
       __pyx_v_unique = ((bool)0);
@@ -42291,21 +42514,21 @@ 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, 4093, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4136, __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, 4093, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4136, __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":4093
+  /* "pywrapfst.pyx":4136
  * 
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,             # <<<<<<<<<<<<<<
- *                                float delta=fst.kShortestDelta,
- *                                int32 nshortest=1,
+ * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
+ *                               float delta=fst.kShortestDelta,
+ *                               int32 nshortest=1,
  */
 
   /* function exit code */
@@ -42317,7 +42540,7 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, float __pyx_v_delta, __pyx_t_10basictypes_int32 __pyx_v_nshortest, __pyx_t_10basictypes_int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight) {
+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) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -42331,7 +42554,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, 4093, __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, 4136, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42348,23 +42571,23 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4145
+/* "pywrapfst.pyx":4188
  * 
  * 
- * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
+ * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
  *   """
  *   state_map(ifst, map_type)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst__map __pyx_t_2;
   __Pyx_RefNannySetupContext("statemap", 0);
 
-  /* "pywrapfst.pyx":4168
+  /* "pywrapfst.pyx":4211
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, 1., None)             # <<<<<<<<<<<<<<
@@ -42377,16 +42600,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
   __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, 4168, __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, 4211, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4145
+  /* "pywrapfst.pyx":4188
  * 
  * 
- * cpdef _Fst statemap(_Fst ifst, map_type):             # <<<<<<<<<<<<<<
+ * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
  *   """
  *   state_map(ifst, map_type)
  */
@@ -42406,7 +42629,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_statemap(struct __py
 static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_58statemap[] = "\n  state_map(ifst, map_type)\n\n  Constructively applies a transform to all states.\n\n  This operation transforms each state using one of the following:\n\n    * arc_sum: sums weights of identically-labeled multi-arcs.\n    * arc_unique: deletes non-unique identically-labeled multi-arcs.\n    * identity: maps to self.\n\n  Args:\n    ifst: The input FST.\n    map_type: A string matching a known mapping operation; one of: \"arc_sum\",\n        \"arc_unique\", \"identity\".\n\n  Returns:\n    An FST with states remapped.\n\n  Raises:\n    FstArgError: Unknown 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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_map_type = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
@@ -42434,11 +42657,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, 4145, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4188, __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, 4145, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4188, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -42446,18 +42669,18 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[0]);
+    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_map_type = values[1];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4145, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4188, __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, 4145, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4188, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_58statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
@@ -42469,13 +42692,13 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type) {
+static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 4145, __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, 4188, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42492,23 +42715,23 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4171
+/* "pywrapfst.pyx":4214
  * 
  * 
- * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
  *   """
  *   synchronize(ifst)
  */
 
 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) {
+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;
-  struct __pyx_obj_9pywrapfst__MutableFst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4191
+  /* "pywrapfst.pyx":4234
  *   """
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
@@ -42517,11 +42740,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4191, __pyx_L1_error)
+    __PYX_ERR(0, 4234, __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":4192
+  /* "pywrapfst.pyx":4235
  *   cdef unique_ptr[fst.VectorFstClass] tfst
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())             # <<<<<<<<<<<<<<
@@ -42530,11 +42753,11 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4192, __pyx_L1_error)
+    __PYX_ERR(0, 4235, __pyx_L1_error)
   }
   fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get());
 
-  /* "pywrapfst.pyx":4193
+  /* "pywrapfst.pyx":4236
  *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.Synchronize(deref(ifst._fst), tfst.get())
  *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -42542,16 +42765,16 @@ static struct __pyx_obj_9pywrapfst__MutableFst *__pyx_f_9pywrapfst_synchronize(s
  * 
  */
   __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, 4193, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__MutableFst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4171
+  /* "pywrapfst.pyx":4214
  * 
  * 
- * cpdef _MutableFst synchronize(_Fst ifst):             # <<<<<<<<<<<<<<
+ * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
  *   """
  *   synchronize(ifst)
  */
@@ -42574,8 +42797,8 @@ static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObjec
   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, 4171, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_60synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_v_ifst));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4214, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_60synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_ifst));
 
   /* function exit code */
   goto __pyx_L0;
@@ -42586,13 +42809,13 @@ static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 4171, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42609,7 +42832,7 @@ static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4250
+/* "pywrapfst.pyx":4293
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42637,7 +42860,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
     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};
 
-    /* "pywrapfst.pyx":4253
+    /* "pywrapfst.pyx":4296
  *                 string fst_type=b"vector",
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
@@ -42646,7 +42869,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":4254
+    /* "pywrapfst.pyx":4297
  *                 string arc_type=b"standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
@@ -42655,7 +42878,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":4255
+    /* "pywrapfst.pyx":4298
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -42753,7 +42976,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, 4250, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4293, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42782,23 +43005,23 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       }
     }
     if (values[0]) {
-      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4251, __pyx_L3_error)
+      __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__50;
+      __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, 4252, __pyx_L3_error)
+      __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__51;
+      __pyx_v_arc_type = __pyx_k__52;
     }
     __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, 4256, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4299, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4256
+      /* "pywrapfst.pyx":4299
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -42808,10 +43031,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, 4257, __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, 4300, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4257
+      /* "pywrapfst.pyx":4300
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -42821,10 +43044,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, 4258, __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, 4301, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4258
+      /* "pywrapfst.pyx":4301
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -42834,10 +43057,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, 4259, __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, 4302, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4259
+      /* "pywrapfst.pyx":4302
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -42847,10 +43070,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, 4260, __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, 4303, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4260
+      /* "pywrapfst.pyx":4303
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -42862,18 +43085,18 @@ 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, 4250, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4293, __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, 4253, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4254, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4255, __pyx_L1_error)
+  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)
   __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":4250
+  /* "pywrapfst.pyx":4293
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -42897,10 +43120,10 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   std::string __pyx_t_2;
   int __pyx_t_3;
   int __pyx_t_4;
-  fst::SymbolTable *__pyx_t_5;
+  fst::SymbolTable const *__pyx_t_5;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4261
+  /* "pywrapfst.pyx":4304
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -42909,212 +43132,212 @@ 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, 4261, __pyx_L1_error)
+    __PYX_ERR(0, 4304, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4262
+  /* "pywrapfst.pyx":4305
  *                 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, 4262, __pyx_L1_error)
+  __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, 4262, __pyx_L1_error)
+  __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;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4262, __pyx_L1_error)
+    __PYX_ERR(0, 4305, __pyx_L1_error)
   }
   __pyx_v_self->_fst_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4263
+  /* "pywrapfst.pyx":4306
  *     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, 4263, __pyx_L1_error)
+  __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, 4263, __pyx_L1_error)
+  __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;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4263, __pyx_L1_error)
+    __PYX_ERR(0, 4306, __pyx_L1_error)
   }
   __pyx_v_self->_arc_type = __pyx_t_2;
 
-  /* "pywrapfst.pyx":4264
+  /* "pywrapfst.pyx":4307
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
  *     if isymbols is not None:
- *       self._isymbols = isymbols._table
+ *       self._isymbols = isymbols._raw_ptr_or_raise()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4264, __pyx_L1_error)
+    __PYX_ERR(0, 4307, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4265
+  /* "pywrapfst.pyx":4308
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *       self._isymbols = isymbols._table
+ *       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) {
 
-    /* "pywrapfst.pyx":4266
+    /* "pywrapfst.pyx":4309
  *     self._isymbols = NULL
  *     if isymbols is not None:
- *       self._isymbols = isymbols._table             # <<<<<<<<<<<<<<
+ *       self._isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     self._osymbols = NULL
  *     if osymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4266, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 4309, __pyx_L1_error)
     }
-    __pyx_t_5 = __pyx_v_isymbols->__pyx_base.__pyx_base._table;
+    __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)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-      __PYX_ERR(0, 4266, __pyx_L1_error)
+      __PYX_ERR(0, 4309, __pyx_L1_error)
     }
     __pyx_v_self->_isymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4265
+    /* "pywrapfst.pyx":4308
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
- *       self._isymbols = isymbols._table
+ *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":4267
+  /* "pywrapfst.pyx":4310
  *     if isymbols is not None:
- *       self._isymbols = isymbols._table
+ *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
  *     if osymbols is not None:
- *       self._osymbols = osymbols._table
+ *       self._osymbols = osymbols._raw_ptr_or_raise()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4267, __pyx_L1_error)
+    __PYX_ERR(0, 4310, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4268
- *       self._isymbols = isymbols._table
+  /* "pywrapfst.pyx":4311
+ *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *       self._osymbols = osymbols._table
+ *       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) {
 
-    /* "pywrapfst.pyx":4269
+    /* "pywrapfst.pyx":4312
  *     self._osymbols = NULL
  *     if osymbols is not None:
- *       self._osymbols = osymbols._table             # <<<<<<<<<<<<<<
+ *       self._osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4269, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 4312, __pyx_L1_error)
     }
-    __pyx_t_5 = __pyx_v_osymbols->__pyx_base.__pyx_base._table;
+    __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)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-      __PYX_ERR(0, 4269, __pyx_L1_error)
+      __PYX_ERR(0, 4312, __pyx_L1_error)
     }
     __pyx_v_self->_osymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4268
- *       self._isymbols = isymbols._table
+    /* "pywrapfst.pyx":4311
+ *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
- *       self._osymbols = osymbols._table
+ *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  */
   }
 
-  /* "pywrapfst.pyx":4270
+  /* "pywrapfst.pyx":4313
  *     if osymbols is not None:
- *       self._osymbols = osymbols._table
+ *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
  *     if ssymbols is not None:
- *       self._ssymbols = ssymbols._table
+ *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4270, __pyx_L1_error)
+    __PYX_ERR(0, 4313, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4271
- *       self._osymbols = osymbols._table
+  /* "pywrapfst.pyx":4314
+ *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       self._ssymbols = ssymbols._table
+ *       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) {
 
-    /* "pywrapfst.pyx":4272
+    /* "pywrapfst.pyx":4315
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
- *       self._ssymbols = ssymbols._table             # <<<<<<<<<<<<<<
+ *       self._ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-      __PYX_ERR(0, 4272, __pyx_L1_error)
+      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
+      __PYX_ERR(0, 4315, __pyx_L1_error)
     }
-    __pyx_t_5 = __pyx_v_ssymbols->__pyx_base.__pyx_base._table;
+    __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)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-      __PYX_ERR(0, 4272, __pyx_L1_error)
+      __PYX_ERR(0, 4315, __pyx_L1_error)
     }
     __pyx_v_self->_ssymbols = __pyx_t_5;
 
-    /* "pywrapfst.pyx":4271
- *       self._osymbols = osymbols._table
+    /* "pywrapfst.pyx":4314
+ *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
- *       self._ssymbols = ssymbols._table
+ *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor
  */
   }
 
-  /* "pywrapfst.pyx":4273
+  /* "pywrapfst.pyx":4316
  *     if ssymbols is not None:
- *       self._ssymbols = ssymbols._table
+ *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4273, __pyx_L1_error)
+    __PYX_ERR(0, 4316, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4274
- *       self._ssymbols = ssymbols._table
+  /* "pywrapfst.pyx":4317
+ *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
  *     self._keep_osymbols = keep_osymbols
@@ -43122,11 +43345,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, 4274, __pyx_L1_error)
+    __PYX_ERR(0, 4317, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4275
+  /* "pywrapfst.pyx":4318
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -43135,11 +43358,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, 4275, __pyx_L1_error)
+    __PYX_ERR(0, 4318, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4276
+  /* "pywrapfst.pyx":4319
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -43148,24 +43371,24 @@ 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, 4276, __pyx_L1_error)
+    __PYX_ERR(0, 4319, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4277
+  /* "pywrapfst.pyx":4320
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
  * 
- *   cpdef _Fst compile(self):
+ *   cpdef Fst compile(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4277, __pyx_L1_error)
+    __PYX_ERR(0, 4320, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4250
+  /* "pywrapfst.pyx":4293
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
@@ -43185,18 +43408,18 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4279
+/* "pywrapfst.pyx":4322
  *     self._allow_negative_labels = allow_negative_labels
  * 
- *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
  *     """
  *     compile()
  */
 
 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) {
+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;
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -43213,7 +43436,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(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_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4279, __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, 4322, __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));
@@ -43230,11 +43453,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(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, 4279, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4322, __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, 4279, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4322, __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;
         goto __pyx_L0;
@@ -43252,7 +43475,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     #endif
   }
 
-  /* "pywrapfst.pyx":4294
+  /* "pywrapfst.pyx":4337
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -43261,10 +43484,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4294, __pyx_L1_error)
+    __PYX_ERR(0, 4337, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4296
+  /* "pywrapfst.pyx":4339
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
  *                                       b"<pywrapfst>",
  *                                       self._fst_type,             # <<<<<<<<<<<<<<
@@ -43273,10 +43496,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4296, __pyx_L1_error)
+    __PYX_ERR(0, 4339, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4297
+  /* "pywrapfst.pyx":4340
  *                                       b"<pywrapfst>",
  *                                       self._fst_type,
  *                                       self._arc_type,             # <<<<<<<<<<<<<<
@@ -43285,10 +43508,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4297, __pyx_L1_error)
+    __PYX_ERR(0, 4340, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4298
+  /* "pywrapfst.pyx":4341
  *                                       self._fst_type,
  *                                       self._arc_type,
  *                                       self._isymbols,             # <<<<<<<<<<<<<<
@@ -43297,10 +43520,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4298, __pyx_L1_error)
+    __PYX_ERR(0, 4341, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4299
+  /* "pywrapfst.pyx":4342
  *                                       self._arc_type,
  *                                       self._isymbols,
  *                                       self._osymbols,             # <<<<<<<<<<<<<<
@@ -43309,10 +43532,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4299, __pyx_L1_error)
+    __PYX_ERR(0, 4342, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4300
+  /* "pywrapfst.pyx":4343
  *                                       self._isymbols,
  *                                       self._osymbols,
  *                                       self._ssymbols,             # <<<<<<<<<<<<<<
@@ -43321,10 +43544,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4300, __pyx_L1_error)
+    __PYX_ERR(0, 4343, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4301
+  /* "pywrapfst.pyx":4344
  *                                       self._osymbols,
  *                                       self._ssymbols,
  *                                       self._acceptor,             # <<<<<<<<<<<<<<
@@ -43333,10 +43556,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4301, __pyx_L1_error)
+    __PYX_ERR(0, 4344, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4302
+  /* "pywrapfst.pyx":4345
  *                                       self._ssymbols,
  *                                       self._acceptor,
  *                                       self._keep_isymbols,             # <<<<<<<<<<<<<<
@@ -43345,10 +43568,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4302, __pyx_L1_error)
+    __PYX_ERR(0, 4345, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4303
+  /* "pywrapfst.pyx":4346
  *                                       self._acceptor,
  *                                       self._keep_isymbols,
  *                                       self._keep_osymbols,             # <<<<<<<<<<<<<<
@@ -43357,10 +43580,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4303, __pyx_L1_error)
+    __PYX_ERR(0, 4346, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4304
+  /* "pywrapfst.pyx":4347
  *                                       self._keep_isymbols,
  *                                       self._keep_osymbols,
  *                                       self._keep_state_numbering,             # <<<<<<<<<<<<<<
@@ -43369,10 +43592,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4304, __pyx_L1_error)
+    __PYX_ERR(0, 4347, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4305
+  /* "pywrapfst.pyx":4348
  *                                       self._keep_osymbols,
  *                                       self._keep_state_numbering,
  *                                       self._allow_negative_labels))             # <<<<<<<<<<<<<<
@@ -43381,10 +43604,10 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4305, __pyx_L1_error)
+    __PYX_ERR(0, 4348, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4294
+  /* "pywrapfst.pyx":4337
  *     """
  *     cdef unique_ptr[fst.FstClass] tfst
  *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
@@ -43393,7 +43616,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   __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":4306
+  /* "pywrapfst.pyx":4349
  *                                       self._keep_state_numbering,
  *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -43402,11 +43625,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4306, __pyx_L1_error)
+    __PYX_ERR(0, 4349, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4307
+  /* "pywrapfst.pyx":4350
  *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -43416,14 +43639,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
   __pyx_t_5 = ((__pyx_v_tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4308
+    /* "pywrapfst.pyx":4351
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
  *     return _init_XFst(tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4308, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4351, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -43437,14 +43660,14 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
     }
     __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, 4308, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4351, __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, 4308, __pyx_L1_error)
+    __PYX_ERR(0, 4351, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4307
+    /* "pywrapfst.pyx":4350
  *                                       self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
@@ -43453,7 +43676,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  */
   }
 
-  /* "pywrapfst.pyx":4309
+  /* "pywrapfst.pyx":4352
  *     if tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  *     return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
@@ -43461,16 +43684,16 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_8Compiler_compile(st
  *   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, 4309, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4279
+  /* "pywrapfst.pyx":4322
  *     self._allow_negative_labels = allow_negative_labels
  * 
- *   cpdef _Fst compile(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
  *     """
  *     compile()
  */
@@ -43509,7 +43732,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4279, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43526,7 +43749,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4311
+/* "pywrapfst.pyx":4354
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -43555,7 +43778,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, 4311, __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, 4354, __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);
@@ -43571,7 +43794,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, 4311, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __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;
@@ -43591,17 +43814,17 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     #endif
   }
 
-  /* "pywrapfst.pyx":4327
+  /* "pywrapfst.pyx":4370
  *       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')
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4327, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":4328
+  /* "pywrapfst.pyx":4371
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -43619,7 +43842,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4329
+    /* "pywrapfst.pyx":4372
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')             # <<<<<<<<<<<<<<
@@ -43628,7 +43851,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
     (void)(__pyx_v_line.append(((char const *)"\n")));
 
-    /* "pywrapfst.pyx":4328
+    /* "pywrapfst.pyx":4371
  *     """
  *     cdef string line = tostring(expression)
  *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
@@ -43637,7 +43860,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   }
 
-  /* "pywrapfst.pyx":4330
+  /* "pywrapfst.pyx":4373
  *     if not line.empty() and line.back() != b'\n':
  *       line.append(b'\n')
  *     deref(self._sstrm) << line             # <<<<<<<<<<<<<<
@@ -43646,11 +43869,11 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4330, __pyx_L1_error)
+    __PYX_ERR(0, 4373, __pyx_L1_error)
   }
   (void)(((*__pyx_v_self->_sstrm) << __pyx_v_line));
 
-  /* "pywrapfst.pyx":4311
+  /* "pywrapfst.pyx":4354
  *     return _init_XFst(tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
@@ -43690,7 +43913,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __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, 4311, __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, 4354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43738,7 +43961,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_6__reduce_cython__(CYTHON_UNUSED
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__52, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__53, 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;
@@ -43791,7 +44014,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__54, 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;
@@ -43814,7 +44037,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4352
+/* "pywrapfst.pyx":4395
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -43849,28 +44072,28 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4353
+  /* "pywrapfst.pyx":4396
  * 
  *   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, 4353, __pyx_L1_error)
+  __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":4354
+  /* "pywrapfst.pyx":4397
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(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, 4354, __pyx_L1_error)
+  __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, 4354, __pyx_L1_error)
+  __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, 4354, __pyx_L1_error)
+  __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;
@@ -43886,7 +44109,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4354, __pyx_L1_error)
+  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;
@@ -43902,14 +44125,14 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4353, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4396, __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, 4353, __pyx_L1_error)
+  __PYX_ERR(0, 4396, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4352
+  /* "pywrapfst.pyx":4395
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -43931,7 +44154,7 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4356
+/* "pywrapfst.pyx":4399
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -43964,7 +44187,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4357
+  /* "pywrapfst.pyx":4400
  * 
  *   def __repr__(self):
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -43972,15 +44195,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
  *   @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, 4357, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4357, __pyx_L1_error)
+    __PYX_ERR(0, 4400, __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, 4357, __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, 4357, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -43997,7 +44220,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #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, 4357, __pyx_L1_error)
+    __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;
@@ -44007,7 +44230,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   #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, 4357, __pyx_L1_error)
+    __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;
@@ -44015,7 +44238,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4357, __pyx_L1_error)
+    __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;
@@ -44026,7 +44249,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
     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, 4357, __pyx_L1_error)
+    __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;
   }
@@ -44035,7 +44258,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4356
+  /* "pywrapfst.pyx":4399
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -44059,7 +44282,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4360
+/* "pywrapfst.pyx":4403
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44103,7 +44326,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("open", 0);
 
-  /* "pywrapfst.pyx":4379
+  /* "pywrapfst.pyx":4422
  *     """
  *     cdef vector[string] source_strings
  *     for source in sources:             # <<<<<<<<<<<<<<
@@ -44114,30 +44337,30 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   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, 4379, __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, 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, 4379, __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, 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":4380
+    /* "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))
  */
-    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4380, __pyx_L1_error)
+    __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, 4380, __pyx_L1_error)
+      __PYX_ERR(0, 4423, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":4379
+    /* "pywrapfst.pyx":4422
  *     """
  *     cdef vector[string] source_strings
  *     for source in sources:             # <<<<<<<<<<<<<<
@@ -44147,7 +44370,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4382
+  /* "pywrapfst.pyx":4425
  *       source_strings.push_back(tostring(source))
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(source_strings))             # <<<<<<<<<<<<<<
@@ -44156,7 +44379,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   __pyx_v_tfar.reset(fst::script::FarReaderClass::Open(__pyx_v_source_strings));
 
-  /* "pywrapfst.pyx":4383
+  /* "pywrapfst.pyx":4426
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
@@ -44166,16 +44389,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_t_5 = ((__pyx_v_tfar.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4384
+    /* "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())
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4384, __pyx_L1_error)
+    __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, 4384, __pyx_L1_error)
+    __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))) {
@@ -44189,7 +44412,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     }
     __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, 4384, __pyx_L1_error)
+    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;
@@ -44205,14 +44428,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
     __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, 4384, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4427, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4384, __pyx_L1_error)
+    __PYX_ERR(0, 4427, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4383
+    /* "pywrapfst.pyx":4426
  *     cdef unique_ptr[fst.FarReaderClass] tfar
  *     tfar.reset(fst.FarReaderClass.Open(source_strings))
  *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
@@ -44221,19 +44444,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   }
 
-  /* "pywrapfst.pyx":4385
+  /* "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
  */
-  __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, 4385, __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, 4428, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4386
+  /* "pywrapfst.pyx":4429
  *       raise FstIOError("Read failed: {!r}".format(sources))
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())             # <<<<<<<<<<<<<<
@@ -44242,11 +44465,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4386, __pyx_L1_error)
+    __PYX_ERR(0, 4429, __pyx_L1_error)
   }
   __pyx_v_result->_reader.reset(__pyx_v_tfar.release());
 
-  /* "pywrapfst.pyx":4387
+  /* "pywrapfst.pyx":4430
  *     cdef FarReader result = FarReader.__new__(FarReader)
  *     result._reader.reset(tfar.release())
  *     return result             # <<<<<<<<<<<<<<
@@ -44258,7 +44481,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4360
+  /* "pywrapfst.pyx":4403
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44283,7 +44506,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4389
+/* "pywrapfst.pyx":4432
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -44310,7 +44533,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, 4389, __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, 4432, __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);
@@ -44326,10 +44549,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, 4389, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4432, __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, 4389, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44348,7 +44571,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4395
+  /* "pywrapfst.pyx":4438
  *     Returns a string indicating the arc type.
  *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
@@ -44357,12 +44580,12 @@ 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, 4395, __pyx_L1_error)
+    __PYX_ERR(0, 4438, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4389
+  /* "pywrapfst.pyx":4432
  *     return result
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -44403,7 +44626,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4389, __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, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44420,7 +44643,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4397
+/* "pywrapfst.pyx":4440
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -44447,7 +44670,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, 4397, __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, 4440, __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);
@@ -44463,10 +44686,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, 4397, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4440, __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, 4397, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44485,7 +44708,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4406
+  /* "pywrapfst.pyx":4449
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -44494,12 +44717,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, 4406, __pyx_L1_error)
+    __PYX_ERR(0, 4449, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4397
+  /* "pywrapfst.pyx":4440
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -44540,7 +44763,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   __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, 4397, __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, 4440, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44557,7 +44780,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4408
+/* "pywrapfst.pyx":4451
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -44584,7 +44807,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, 4408, __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, 4451, __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);
@@ -44600,10 +44823,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, 4408, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4451, __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, 4408, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44622,7 +44845,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4417
+  /* "pywrapfst.pyx":4460
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -44631,12 +44854,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, 4417, __pyx_L1_error)
+    __PYX_ERR(0, 4460, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4408
+  /* "pywrapfst.pyx":4451
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -44677,7 +44900,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4408, __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, 4451, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44694,7 +44917,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4419
+/* "pywrapfst.pyx":4462
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -44721,7 +44944,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, 4419, __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, 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_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44737,10 +44960,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, 4419, __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, 4419, __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;
@@ -44759,21 +44982,21 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4420
+  /* "pywrapfst.pyx":4463
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
  * 
- *   cpdef bool find(self, key) except *:
+ *   cpdef bool find(self, key):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4420, __pyx_L1_error)
+    __PYX_ERR(0, 4463, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4419
+  /* "pywrapfst.pyx":4462
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -44813,7 +45036,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 4419, __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, 4462, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44830,10 +45053,10 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4422
+/* "pywrapfst.pyx":4465
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
- *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
+ *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
  *     """
  *     find(self, key)
  */
@@ -44858,7 +45081,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, 4422, __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, 4465, __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);
@@ -44874,10 +45097,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, 4422, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4465, __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, 4422, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44896,25 +45119,25 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4435
+  /* "pywrapfst.pyx":4478
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
  * 
- *   cpdef _Fst get_fst(self):
+ *   cpdef Fst get_fst(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4435, __pyx_L1_error)
+    __PYX_ERR(0, 4478, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4435, __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_r = __pyx_v_self->_reader.get()->Find(__pyx_t_6);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4422
+  /* "pywrapfst.pyx":4465
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
- *   cpdef bool find(self, key) except *:             # <<<<<<<<<<<<<<
+ *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
  *     """
  *     find(self, key)
  */
@@ -44925,7 +45148,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst.FarReader.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_WriteUnraisable("pywrapfst.FarReader.find", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -44949,20 +45172,18 @@ static PyObject *__pyx_pw_9pywrapfst_9FarReader_15find(PyObject *__pyx_v_self, P
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  bool __pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_1 = NULL;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4422, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4422, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_r = __pyx_t_2;
-  __pyx_t_2 = 0;
+  __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_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_2);
+  __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pywrapfst.FarReader.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -44971,17 +45192,17 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4437
+/* "pywrapfst.pyx":4480
  *     return self._reader.get().Find(tostring(key))
  * 
- *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
  *     """
  *     get_fst(self)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_9FarReader_17get_fst(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst__Fst *__pyx_r = NULL;
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, int __pyx_skip_dispatch) {
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -44997,7 +45218,7 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     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, 4437, __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, 4480, __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));
@@ -45014,11 +45235,11 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
         }
         __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, 4437, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4480, __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, 4437, __pyx_L1_error)
-        __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_2);
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4480, __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;
         goto __pyx_L0;
@@ -45036,44 +45257,28 @@ static struct __pyx_obj_9pywrapfst__Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(s
     #endif
   }
 
-  /* "pywrapfst.pyx":4446
+  /* "pywrapfst.pyx":4489
  *       A copy of the FST at the current position.
  *     """
- *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
- *         deref(self._reader.get().GetFstClass())))
- * 
- */
-  __Pyx_XDECREF(((PyObject *)__pyx_r));
-
-  /* "pywrapfst.pyx":4447
- *     """
- *     return _init_XFst(new fst.FstClass(
- *         deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
+ *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
  * 
  *   cpdef string get_key(self):
  */
+  __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, 4447, __pyx_L1_error)
+    __PYX_ERR(0, 4489, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":4446
- *       A copy of the FST at the current position.
- *     """
- *     return _init_XFst(new fst.FstClass(             # <<<<<<<<<<<<<<
- *         deref(self._reader.get().GetFstClass())))
- * 
- */
-  __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, 4446, __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_GOTREF(__pyx_t_1);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst__Fst *)__pyx_t_1);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4437
+  /* "pywrapfst.pyx":4480
  *     return self._reader.get().Find(tostring(key))
  * 
- *   cpdef _Fst get_fst(self):             # <<<<<<<<<<<<<<
+ *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
  *     """
  *     get_fst(self)
  */
@@ -45112,7 +45317,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4437, __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, 4480, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45129,8 +45334,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4449
- *         deref(self._reader.get().GetFstClass())))
+/* "pywrapfst.pyx":4491
+ *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
  *     """
@@ -45156,7 +45361,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, 4449, __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, 4491, __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);
@@ -45172,10 +45377,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, 4449, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4491, __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, 4449, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45194,7 +45399,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":4458
+  /* "pywrapfst.pyx":4500
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -45203,13 +45408,13 @@ 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, 4458, __pyx_L1_error)
+    __PYX_ERR(0, 4500, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4449
- *         deref(self._reader.get().GetFstClass())))
+  /* "pywrapfst.pyx":4491
+ *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
  *     """
@@ -45249,7 +45454,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4449, __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, 4491, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45266,7 +45471,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4460
+/* "pywrapfst.pyx":4502
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45291,7 +45496,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, 4460, __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, 4502, __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);
@@ -45307,7 +45512,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, 4460, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4502, __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;
@@ -45327,7 +45532,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4466
+  /* "pywrapfst.pyx":4508
  *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
@@ -45336,11 +45541,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, 4466, __pyx_L1_error)
+    __PYX_ERR(0, 4508, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4460
+  /* "pywrapfst.pyx":4502
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45380,7 +45585,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_1 = NULL;
   __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, 4460, __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, 4502, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45397,7 +45602,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4468
+/* "pywrapfst.pyx":4510
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -45422,7 +45627,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, 4468, __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, 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_23reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45438,7 +45643,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, 4468, __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;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -45458,7 +45663,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4474
+  /* "pywrapfst.pyx":4516
  *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
@@ -45467,11 +45672,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, 4474, __pyx_L1_error)
+    __PYX_ERR(0, 4516, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4468
+  /* "pywrapfst.pyx":4510
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -45511,7 +45716,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4468, __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, 4510, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45528,7 +45733,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4476
+/* "pywrapfst.pyx":4518
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -45557,7 +45762,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4477
+  /* "pywrapfst.pyx":4519
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -45566,13 +45771,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, 4477, __pyx_L1_error)
+    __PYX_ERR(0, 4519, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4477, __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_2 = (__pyx_v_self->_reader.get()->Find(__pyx_t_1) != 0);
   if (likely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":4478
+    /* "pywrapfst.pyx":4520
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):
  *       return self.get_fst()             # <<<<<<<<<<<<<<
@@ -45582,15 +45787,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, 4478, __pyx_L1_error)
+      __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, 4478, __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_GOTREF(__pyx_t_3);
     __pyx_r = __pyx_t_3;
     __pyx_t_3 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":4477
+    /* "pywrapfst.pyx":4519
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -45599,7 +45804,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4480
+  /* "pywrapfst.pyx":4522
  *       return self.get_fst()
  *     else:
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
@@ -45607,14 +45812,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  * 
  */
   /*else*/ {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4480, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 4480, __pyx_L1_error)
+    __PYX_ERR(0, 4522, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4476
+  /* "pywrapfst.pyx":4518
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -45664,7 +45869,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__54, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__55, 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;
@@ -45717,7 +45922,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__55, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__56, 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;
@@ -45740,7 +45945,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4503
+/* "pywrapfst.pyx":4545
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -45775,28 +45980,28 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_t_6 = NULL;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4504
+  /* "pywrapfst.pyx":4546
  * 
  *   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, 4504, __pyx_L1_error)
+  __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":4505
+  /* "pywrapfst.pyx":4547
  *   def __init__(self):
  *     raise FstDeletedConstructorError(
  *         "Cannot construct {}".format(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, 4505, __pyx_L1_error)
+  __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, 4505, __pyx_L1_error)
+  __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, 4505, __pyx_L1_error)
+  __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;
@@ -45812,7 +46017,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4505, __pyx_L1_error)
+  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;
@@ -45828,14 +46033,14 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __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, 4504, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4546, __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, 4504, __pyx_L1_error)
+  __PYX_ERR(0, 4546, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4503
+  /* "pywrapfst.pyx":4545
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
@@ -45857,7 +46062,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4507
+/* "pywrapfst.pyx":4549
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -45890,7 +46095,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_t_7 = NULL;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4508
+  /* "pywrapfst.pyx":4550
  * 
  *   def __repr__(self):
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
@@ -45898,15 +46103,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
  *   @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, 4508, __pyx_L1_error)
+  __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);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4508, __pyx_L1_error)
+    __PYX_ERR(0, 4550, __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, 4508, __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, 4508, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
   __pyx_t_5 = NULL;
   __pyx_t_6 = 0;
@@ -45923,7 +46128,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #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, 4508, __pyx_L1_error)
+    __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;
@@ -45933,7 +46138,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   #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, 4508, __pyx_L1_error)
+    __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;
@@ -45941,7 +46146,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   } else
   #endif
   {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4508, __pyx_L1_error)
+    __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;
@@ -45952,7 +46157,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
     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, 4508, __pyx_L1_error)
+    __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;
   }
@@ -45961,7 +46166,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4507
+  /* "pywrapfst.pyx":4549
  *         "Cannot construct {}".format(self.__class__.__name__))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
@@ -45985,7 +46190,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4511
+/* "pywrapfst.pyx":4553
  * 
  *   @classmethod
  *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -46040,7 +46245,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, 4511, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4553, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -46059,7 +46264,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, 4511, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4553, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46088,35 +46293,35 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_t_8 = NULL;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4532
+  /* "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, 4532, __pyx_L1_error)
+  __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":4534
+  /* "pywrapfst.pyx":4576
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(source),             # <<<<<<<<<<<<<<
  *         tostring(arc_type),
  *         ft)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4534, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4576, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4535
+  /* "pywrapfst.pyx":4577
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
  *         tostring(source),
  *         tostring(arc_type),             # <<<<<<<<<<<<<<
  *         ft)
  *     if tfar == NULL:
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4535, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4577, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4533
+  /* "pywrapfst.pyx":4575
  *     """
  *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
  *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
@@ -46125,7 +46330,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   __pyx_v_tfar = fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_v_ft);
 
-  /* "pywrapfst.pyx":4537
+  /* "pywrapfst.pyx":4579
  *         tostring(arc_type),
  *         ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -46135,16 +46340,16 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_t_3 = ((__pyx_v_tfar == NULL) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":4538
+    /* "pywrapfst.pyx":4580
  *         ft)
  *     if tfar == NULL:
  *       raise FstIOError("Open failed: {!r}".format(source))             # <<<<<<<<<<<<<<
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4538, __pyx_L1_error)
+    __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, 4538, __pyx_L1_error)
+    __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_GOTREF(__pyx_t_7);
     __pyx_t_8 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
@@ -46158,7 +46363,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     }
     __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_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4538, __pyx_L1_error)
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4580, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __pyx_t_7 = NULL;
@@ -46174,14 +46379,14 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
     __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, 4538, __pyx_L1_error)
+    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, 4538, __pyx_L1_error)
+    __PYX_ERR(0, 4580, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4537
+    /* "pywrapfst.pyx":4579
  *         tostring(arc_type),
  *         ft)
  *     if tfar == NULL:             # <<<<<<<<<<<<<<
@@ -46190,19 +46395,19 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   }
 
-  /* "pywrapfst.pyx":4539
+  /* "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
  */
-  __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, 4539, __pyx_L1_error)
+  __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;
 
-  /* "pywrapfst.pyx":4540
+  /* "pywrapfst.pyx":4582
  *       raise FstIOError("Open failed: {!r}".format(source))
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)             # <<<<<<<<<<<<<<
@@ -46211,11 +46416,11 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4540, __pyx_L1_error)
+    __PYX_ERR(0, 4582, __pyx_L1_error)
   }
   __pyx_v_result->_writer.reset(__pyx_v_tfar);
 
-  /* "pywrapfst.pyx":4541
+  /* "pywrapfst.pyx":4583
  *     cdef FarWriter result = FarWriter.__new__(FarWriter)
  *     result._writer.reset(tfar)
  *     return result             # <<<<<<<<<<<<<<
@@ -46227,7 +46432,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   __pyx_r = ((PyObject *)__pyx_v_result);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4511
+  /* "pywrapfst.pyx":4553
  * 
  *   @classmethod
  *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
@@ -46251,7 +46456,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4545
+/* "pywrapfst.pyx":4587
  *   # 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):             # <<<<<<<<<<<<<<
@@ -46263,20 +46468,20 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("close", 0);
 
-  /* "pywrapfst.pyx":4546
+  /* "pywrapfst.pyx":4588
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
  * 
- *   cpdef void add(self, key, _Fst ifst) except *:
+ *   cpdef void add(self, key, Fst ifst) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4546, __pyx_L1_error)
+    __PYX_ERR(0, 4588, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4545
+  /* "pywrapfst.pyx":4587
  *   # 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):             # <<<<<<<<<<<<<<
@@ -46292,16 +46497,16 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4548
+/* "pywrapfst.pyx":4590
  *     self._writer.reset()
  * 
- *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add(self, key, ifst)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst, int __pyx_skip_dispatch) {
+static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -46321,7 +46526,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, 4548, __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, 4590, __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);
@@ -46340,7 +46545,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, 4548, __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, 4590, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -46348,13 +46553,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, 4548, __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, 4590, __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, 4548, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4590, __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;
@@ -46365,7 +46570,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, 4548, __pyx_L1_error)
+          __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_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -46387,33 +46592,33 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     #endif
   }
 
-  /* "pywrapfst.pyx":4567
+  /* "pywrapfst.pyx":4608
  *     # 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)):             # <<<<<<<<<<<<<<
  *       raise FstOpError("Incompatible or invalid arc type")
- *     # An error here usually indicates a key out of order.
+ * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4567, __pyx_L1_error)
+    __PYX_ERR(0, 4608, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4567, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4608, __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, 4567, __pyx_L1_error)
+    __PYX_ERR(0, 4608, __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":4568
+    /* "pywrapfst.pyx":4609
  *     # 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")             # <<<<<<<<<<<<<<
- *     # An error here usually indicates a key out of order.
- *     if self._writer.get().Error():
+ * 
+ *   cpdef string arc_type(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4568, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4609, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -46427,77 +46632,26 @@ 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, 4568, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4609, __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, 4568, __pyx_L1_error)
+    __PYX_ERR(0, 4609, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4567
+    /* "pywrapfst.pyx":4608
  *     # 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)):             # <<<<<<<<<<<<<<
  *       raise FstOpError("Incompatible or invalid arc type")
- *     # An error here usually indicates a key out of order.
- */
-  }
-
-  /* "pywrapfst.pyx":4570
- *       raise FstOpError("Incompatible or invalid arc type")
- *     # An error here usually indicates a key out of order.
- *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
- *       raise FstArgError("Key out of order")
- * 
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4570, __pyx_L1_error)
-  }
-  __pyx_t_8 = (__pyx_v_self->_writer.get()->Error() != 0);
-  if (unlikely(__pyx_t_8)) {
-
-    /* "pywrapfst.pyx":4571
- *     # An error here usually indicates a key out of order.
- *     if self._writer.get().Error():
- *       raise FstArgError("Key out of order")             # <<<<<<<<<<<<<<
- * 
- *   cpdef string arc_type(self):
- */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4571, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __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_3);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_2, function);
-      }
-    }
-    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Key_out_of_order) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Key_out_of_order);
-    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4571, __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, 4571, __pyx_L1_error)
-
-    /* "pywrapfst.pyx":4570
- *       raise FstOpError("Incompatible or invalid arc type")
- *     # An error here usually indicates a key out of order.
- *     if self._writer.get().Error():             # <<<<<<<<<<<<<<
- *       raise FstArgError("Key out of order")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":4548
+  /* "pywrapfst.pyx":4590
  *     self._writer.reset()
  * 
- *   cpdef void add(self, key, _Fst ifst) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add(self, key, ifst)
  */
@@ -46517,10 +46671,10 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_9FarWriter_6add[] = "\n    add(self, key, ifst)\n\n    Adds an FST to the FAR.\n\n    This method adds an FST to the FAR which can be retrieved with the\n    specified string key.\n\n    Args:\n      key: The string used to key the input FST.\n      ifst: The FST to write to the FAR.\n\n    Raises:\n      FstArgError: Key out of order.\n      FstOpError: Incompatible or invalid arc type.\n    ";
+static char __pyx_doc_9pywrapfst_9FarWriter_6add[] = "\n    add(self, key, ifst)\n\n    Adds an FST to the FAR.\n\n    This method adds an FST to the FAR which can be retrieved with the\n    specified string key.\n\n    Args:\n      key: The string used to key the input FST.\n      ifst: The FST to write to the FAR.\n\n    Raises:\n      FstOpError: Incompatible or invalid arc type.\n    ";
 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;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add (wrapper)", 0);
@@ -46547,11 +46701,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, 4548, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4590, __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, 4548, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4590, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -46560,17 +46714,17 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_key = values[0];
-    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst__Fst *)values[1]);
+    __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4548, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4590, __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, 4548, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4590, __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 */
@@ -46582,14 +46736,14 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst__Fst *__pyx_v_ifst) {
+static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   __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, 4548, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4548, __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, 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_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46606,8 +46760,8 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4573
- *       raise FstArgError("Key out of order")
+/* "pywrapfst.pyx":4611
+ *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -46633,7 +46787,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, 4573, __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, 4611, __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);
@@ -46649,10 +46803,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, 4573, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4611, __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, 4573, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46671,7 +46825,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4579
+  /* "pywrapfst.pyx":4617
  *     Returns a string indicating the arc type.
  *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
@@ -46680,13 +46834,13 @@ 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, 4579, __pyx_L1_error)
+    __PYX_ERR(0, 4617, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4573
- *       raise FstArgError("Key out of order")
+  /* "pywrapfst.pyx":4611
+ *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -46726,7 +46880,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_1 = NULL;
   __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, 4573, __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, 4611, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46743,7 +46897,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4581
+/* "pywrapfst.pyx":4619
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -46770,7 +46924,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, 4581, __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, 4619, __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);
@@ -46786,10 +46940,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, 4581, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4619, __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, 4581, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46808,7 +46962,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     #endif
   }
 
-  /* "pywrapfst.pyx":4590
+  /* "pywrapfst.pyx":4628
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -46817,12 +46971,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, 4590, __pyx_L1_error)
+    __PYX_ERR(0, 4628, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4581
+  /* "pywrapfst.pyx":4619
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -46863,7 +47017,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_1 = NULL;
   __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, 4581, __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, 4619, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46880,7 +47034,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4592
+/* "pywrapfst.pyx":4630
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -46907,7 +47061,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, 4592, __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, 4630, __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);
@@ -46923,10 +47077,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, 4592, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4630, __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, 4592, __pyx_L1_error)
+        __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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46945,7 +47099,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4598
+  /* "pywrapfst.pyx":4636
  *     Returns a string indicating the FAR type.
  *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
@@ -46954,12 +47108,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, 4598, __pyx_L1_error)
+    __PYX_ERR(0, 4636, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4592
+  /* "pywrapfst.pyx":4630
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -47000,7 +47154,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_t_1 = NULL;
   __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, 4592, __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, 4630, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47017,10 +47171,10 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4601
+/* "pywrapfst.pyx":4639
  * 
  *   # Dictionary-like assignment.
- *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
+ *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
  *     self.add(key, fst)
  * 
  */
@@ -47031,8 +47185,8 @@ static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self,
   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, 4601, __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));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst_Fst, 1, "fst", 0))) __PYX_ERR(0, 4639, __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 */
   goto __pyx_L0;
@@ -47043,28 +47197,28 @@ static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self,
   return __pyx_r;
 }
 
-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) {
+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
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4602
+  /* "pywrapfst.pyx":4640
  *   # Dictionary-like assignment.
- *   def __setitem__(self, key, _Fst fst):
+ *   def __setitem__(self, key, Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "add");
-    __PYX_ERR(0, 4602, __pyx_L1_error)
+    __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, 4602, __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)
 
-  /* "pywrapfst.pyx":4601
+  /* "pywrapfst.pyx":4639
  * 
  *   # Dictionary-like assignment.
- *   def __setitem__(self, key, _Fst fst):             # <<<<<<<<<<<<<<
+ *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
  *     self.add(key, fst)
  * 
  */
@@ -47111,7 +47265,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_16__reduce_cython__(CYTHON_UNUSE
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__56, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__57, 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;
@@ -47164,7 +47318,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_18__setstate_cython__(CYTHON_UNU
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__57, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__58, 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;
@@ -47191,7 +47345,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_18__setstate_cython__(CYTHON_UNU
  * 
  * @cname("__pyx_convert_string_from_py_std__in_string")
  * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *:             # <<<<<<<<<<<<<<
- *     cdef Py_ssize_t length
+ *     cdef Py_ssize_t length = 0
  *     cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length)
  */
 
@@ -47203,9 +47357,18 @@ static std::string __pyx_convert_string_from_py_std__in_string(PyObject *__pyx_v
   char const *__pyx_t_1;
   __Pyx_RefNannySetupContext("__pyx_convert_string_from_py_std__in_string", 0);
 
+  /* "string.from_py":14
+ * @cname("__pyx_convert_string_from_py_std__in_string")
+ * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *:
+ *     cdef Py_ssize_t length = 0             # <<<<<<<<<<<<<<
+ *     cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length)
+ *     return string(data, length)
+ */
+  __pyx_v_length = 0;
+
   /* "string.from_py":15
  * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *:
- *     cdef Py_ssize_t length
+ *     cdef Py_ssize_t length = 0
  *     cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length)             # <<<<<<<<<<<<<<
  *     return string(data, length)
  * 
@@ -47214,7 +47377,7 @@ static std::string __pyx_convert_string_from_py_std__in_string(PyObject *__pyx_v
   __pyx_v_data = __pyx_t_1;
 
   /* "string.from_py":16
- *     cdef Py_ssize_t length
+ *     cdef Py_ssize_t length = 0
  *     cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length)
  *     return string(data, length)             # <<<<<<<<<<<<<<
  * 
@@ -47227,7 +47390,7 @@ static std::string __pyx_convert_string_from_py_std__in_string(PyObject *__pyx_v
  * 
  * @cname("__pyx_convert_string_from_py_std__in_string")
  * cdef string __pyx_convert_string_from_py_std__in_string(object o) except *:             # <<<<<<<<<<<<<<
- *     cdef Py_ssize_t length
+ *     cdef Py_ssize_t length = 0
  *     cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length)
  */
 
@@ -47476,26 +47639,26 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_std__in_st
 
 /* "vector.from_py":45
  * 
- * @cname("__pyx_convert_vector_from_py___pyx_t_10basictypes_int64")
- * cdef vector[X] __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(object o) except *:             # <<<<<<<<<<<<<<
+ * @cname("__pyx_convert_vector_from_py_int64")
+ * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:             # <<<<<<<<<<<<<<
  *     cdef vector[X] v
  *     for item in o:
  */
 
-static std::vector<__pyx_t_10basictypes_int64>  __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(PyObject *__pyx_v_o) {
-  std::vector<__pyx_t_10basictypes_int64>  __pyx_v_v;
+static std::vector<int64>  __pyx_convert_vector_from_py_int64(PyObject *__pyx_v_o) {
+  std::vector<int64>  __pyx_v_v;
   PyObject *__pyx_v_item = NULL;
-  std::vector<__pyx_t_10basictypes_int64>  __pyx_r;
+  std::vector<int64>  __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;
-  __pyx_t_10basictypes_int64 __pyx_t_5;
-  __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py___pyx_t_10basictypes_int64", 0);
+  int64 __pyx_t_5;
+  __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py_int64", 0);
 
   /* "vector.from_py":47
- * cdef vector[X] __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(object o) except *:
+ * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:
  *     cdef vector[X] v
  *     for item in o:             # <<<<<<<<<<<<<<
  *         v.push_back(<X>item)
@@ -47550,11 +47713,11 @@ static std::vector<__pyx_t_10basictypes_int64>  __pyx_convert_vector_from_py___p
  *     return v
  * 
  */
-    __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_v_item); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(1, 48, __pyx_L1_error)
-    __pyx_v_v.push_back(((__pyx_t_10basictypes_int64)__pyx_t_5));
+    __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_v_item); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(1, 48, __pyx_L1_error)
+    __pyx_v_v.push_back(((int64)__pyx_t_5));
 
     /* "vector.from_py":47
- * cdef vector[X] __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(object o) except *:
+ * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:
  *     cdef vector[X] v
  *     for item in o:             # <<<<<<<<<<<<<<
  *         v.push_back(<X>item)
@@ -47575,8 +47738,8 @@ static std::vector<__pyx_t_10basictypes_int64>  __pyx_convert_vector_from_py___p
 
   /* "vector.from_py":45
  * 
- * @cname("__pyx_convert_vector_from_py___pyx_t_10basictypes_int64")
- * cdef vector[X] __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(object o) except *:             # <<<<<<<<<<<<<<
+ * @cname("__pyx_convert_vector_from_py_int64")
+ * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:             # <<<<<<<<<<<<<<
  *     cdef vector[X] v
  *     for item in o:
  */
@@ -47585,7 +47748,7 @@ static std::vector<__pyx_t_10basictypes_int64>  __pyx_convert_vector_from_py___p
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("vector.from_py.__pyx_convert_vector_from_py___pyx_t_10basictypes_int64", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("vector.from_py.__pyx_convert_vector_from_py_int64", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_item);
@@ -47715,7 +47878,12 @@ static PyTypeObject __pyx_type_9pywrapfst_Weight = {
   sizeof(struct __pyx_obj_9pywrapfst_Weight), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_Weight, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -47768,6 +47936,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Weight = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_vtable_9pywrapfst__SymbolTable;
 
@@ -47830,7 +48001,12 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   sizeof(struct __pyx_obj_9pywrapfst__SymbolTable), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst__SymbolTable, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -47883,21 +48059,24 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTable __pyx_vtable_9pywrapfst__EncodeMapperSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView;
 
-static PyObject *__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k) {
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *p;
+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);
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable;
+  p = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
   new((void*)&(p->_mapper)) std::shared_ptr<fst::script::EncodeMapperClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTable(PyObject *o) {
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *p = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *)o;
+static void __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTableView(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *p = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)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;
@@ -47907,17 +48086,22 @@ static void __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTable(PyObject *o) {
   __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst__EncodeMapperSymbolTable[] = {
+static PyMethodDef __pyx_methods_9pywrapfst__EncodeMapperSymbolTableView[] = {
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
+static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTableView = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._EncodeMapperSymbolTable", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable), /*tp_basicsize*/
+  "pywrapfst._EncodeMapperSymbolTableView", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTable, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTableView, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -47926,7 +48110,7 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_24_EncodeMapperSymbolTable_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_28_EncodeMapperSymbolTableView_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -47948,7 +48132,7 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
   0, /*tp_iter*/
   #endif
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__EncodeMapperSymbolTable, /*tp_methods*/
+  __pyx_methods_9pywrapfst__EncodeMapperSymbolTableView, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -47962,7 +48146,7 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
   0, /*tp_init*/
   #endif
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__EncodeMapperSymbolTable, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -47978,21 +48162,24 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTable __pyx_vtable_9pywrapfst__FstSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView __pyx_vtable_9pywrapfst__FstSymbolTableView;
 
-static PyObject *__pyx_tp_new_9pywrapfst__FstSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k) {
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *p;
+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);
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__FstSymbolTable *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__FstSymbolTable;
+  p = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
   new((void*)&(p->_fst)) std::shared_ptr<fst::script::FstClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__FstSymbolTable(PyObject *o) {
-  struct __pyx_obj_9pywrapfst__FstSymbolTable *p = (struct __pyx_obj_9pywrapfst__FstSymbolTable *)o;
+static void __pyx_tp_dealloc_9pywrapfst__FstSymbolTableView(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__FstSymbolTableView *p = (struct __pyx_obj_9pywrapfst__FstSymbolTableView *)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;
@@ -48002,17 +48189,22 @@ static void __pyx_tp_dealloc_9pywrapfst__FstSymbolTable(PyObject *o) {
   __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst__FstSymbolTable[] = {
+static PyMethodDef __pyx_methods_9pywrapfst__FstSymbolTableView[] = {
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
+static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTableView = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._FstSymbolTable", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__FstSymbolTable), /*tp_basicsize*/
+  "pywrapfst._FstSymbolTableView", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__FstSymbolTableView), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__FstSymbolTable, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__FstSymbolTableView, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48021,7 +48213,7 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_15_FstSymbolTable_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_19_FstSymbolTableView_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -48043,7 +48235,7 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
   0, /*tp_iter*/
   #endif
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__FstSymbolTable, /*tp_methods*/
+  __pyx_methods_9pywrapfst__FstSymbolTableView, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48057,7 +48249,7 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
   0, /*tp_init*/
   #endif
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__FstSymbolTable, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__FstSymbolTableView, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48073,6 +48265,9 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable __pyx_vtable_9pywrapfst__MutableSymbolTable;
 
@@ -48098,7 +48293,12 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   sizeof(struct __pyx_obj_9pywrapfst__MutableSymbolTable), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst__SymbolTable, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48159,21 +48359,24 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTable __pyx_vtable_9pywrapfst__MutableFstSymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView __pyx_vtable_9pywrapfst__MutableFstSymbolTableView;
 
-static PyObject *__pyx_tp_new_9pywrapfst__MutableFstSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k) {
-  struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *p;
+static PyObject *__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *p;
   PyObject *o = __pyx_tp_new_9pywrapfst__MutableSymbolTable(t, a, k);
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)o);
-  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__MutableFstSymbolTable;
+  p = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
   new((void*)&(p->_mfst)) std::shared_ptr<fst::script::MutableFstClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTable(PyObject *o) {
-  struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *p = (struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *)o;
+static void __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTableView(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *p = (struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)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;
@@ -48183,17 +48386,22 @@ static void __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTable(PyObject *o) {
   __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst__MutableFstSymbolTable[] = {
+static PyMethodDef __pyx_methods_9pywrapfst__MutableFstSymbolTableView[] = {
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
+static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTableView = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._MutableFstSymbolTable", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__MutableFstSymbolTable), /*tp_basicsize*/
+  "pywrapfst._MutableFstSymbolTableView", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTable, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTableView, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48202,7 +48410,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_22_MutableFstSymbolTable_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_26_MutableFstSymbolTableView_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -48224,7 +48432,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   0, /*tp_iter*/
   #endif
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__MutableFstSymbolTable, /*tp_methods*/
+  __pyx_methods_9pywrapfst__MutableFstSymbolTableView, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48238,7 +48446,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   0, /*tp_init*/
   #endif
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__MutableFstSymbolTable, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__MutableFstSymbolTableView, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48254,6 +48462,9 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable __pyx_vtable_9pywrapfst_SymbolTable;
 
@@ -48291,7 +48502,12 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTable = {
   sizeof(struct __pyx_obj_9pywrapfst_SymbolTable), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_SymbolTable, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48348,11 +48564,13 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTable = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst_SymbolTableIterator __pyx_vtable_9pywrapfst_SymbolTableIterator;
 
-static PyObject *__pyx_tp_new_9pywrapfst_SymbolTableIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst_SymbolTableIterator *p;
+static PyObject *__pyx_tp_new_9pywrapfst__SymbolTableIterator(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst__SymbolTableIterator *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -48360,46 +48578,64 @@ static PyObject *__pyx_tp_new_9pywrapfst_SymbolTableIterator(PyTypeObject *t, CY
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst_SymbolTableIterator *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_SymbolTableIterator;
-  new((void*)&(p->_table)) std::shared_ptr<fst::SymbolTable> ();
-  new((void*)&(p->_siter)) std::unique_ptr<fst::SymbolTableIterator> ();
+  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);
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst_SymbolTableIterator(PyObject *o) {
-  struct __pyx_obj_9pywrapfst_SymbolTableIterator *p = (struct __pyx_obj_9pywrapfst_SymbolTableIterator *)o;
+static void __pyx_tp_dealloc_9pywrapfst__SymbolTableIterator(PyObject *o) {
+  struct __pyx_obj_9pywrapfst__SymbolTableIterator *p = (struct __pyx_obj_9pywrapfst__SymbolTableIterator *)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 (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
   }
   #endif
-  __Pyx_call_destructor(p->_table);
+  PyObject_GC_UnTrack(o);
   __Pyx_call_destructor(p->_siter);
+  Py_CLEAR(p->_table);
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__(self);}
+static int __pyx_tp_traverse_9pywrapfst__SymbolTableIterator(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_9pywrapfst__SymbolTableIterator *p = (struct __pyx_obj_9pywrapfst__SymbolTableIterator *)o;
+  if (p->_table) {
+    e = (*v)(((PyObject *)p->_table), a); if (e) return e;
+  }
+  return 0;
+}
+
+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);
+  Py_XDECREF(tmp);
+  return 0;
+}
 
-static PyMethodDef __pyx_methods_9pywrapfst_SymbolTableIterator[] = {
-  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
-  {"done", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_9done, METH_NOARGS, __pyx_doc_9pywrapfst_19SymbolTableIterator_8done},
-  {"next", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_11next, METH_NOARGS, __pyx_doc_9pywrapfst_19SymbolTableIterator_10next},
-  {"reset", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_13reset, METH_NOARGS, __pyx_doc_9pywrapfst_19SymbolTableIterator_12reset},
-  {"symbol", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_15symbol, METH_NOARGS, __pyx_doc_9pywrapfst_19SymbolTableIterator_14symbol},
-  {"value", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_17value, METH_NOARGS, __pyx_doc_9pywrapfst_19SymbolTableIterator_16value},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_19__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_19SymbolTableIterator_21__setstate_cython__, METH_O, 0},
+static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__(self);}
+
+static PyMethodDef __pyx_methods_9pywrapfst__SymbolTableIterator[] = {
+  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__, METH_NOARGS|METH_COEXIST, 0},
+  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_20_SymbolTableIterator_9__reduce_cython__, METH_NOARGS, 0},
+  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_20_SymbolTableIterator_11__setstate_cython__, METH_O, 0},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
+static PyTypeObject __pyx_type_9pywrapfst__SymbolTableIterator = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst.SymbolTableIterator", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst_SymbolTableIterator), /*tp_basicsize*/
+  "pywrapfst._SymbolTableIterator", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst__SymbolTableIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst_SymbolTableIterator, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst__SymbolTableIterator, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48408,7 +48644,7 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_19SymbolTableIterator_1__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_20_SymbolTableIterator_1__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
@@ -48418,15 +48654,15 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   0, /*tp_getattro*/
   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  SymbolTableIterator(syms)\n\n  This class is used for iterating over a symbol table.\n  ", /*tp_doc*/
-  0, /*tp_traverse*/
-  0, /*tp_clear*/
+  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*/
+  __pyx_tp_traverse_9pywrapfst__SymbolTableIterator, /*tp_traverse*/
+  __pyx_tp_clear_9pywrapfst__SymbolTableIterator, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_19SymbolTableIterator_5__iter__, /*tp_iter*/
-  __pyx_pw_9pywrapfst_19SymbolTableIterator_7__next__, /*tp_iternext*/
-  __pyx_methods_9pywrapfst_SymbolTableIterator, /*tp_methods*/
+  __pyx_pw_9pywrapfst_20_SymbolTableIterator_5__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__, /*tp_iternext*/
+  __pyx_methods_9pywrapfst__SymbolTableIterator, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48434,9 +48670,9 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_19SymbolTableIterator_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst_SymbolTableIterator, /*tp_new*/
+  __pyx_tp_new_9pywrapfst__SymbolTableIterator, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48452,6 +48688,9 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTableIterator = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper __pyx_vtable_9pywrapfst_EncodeMapper;
 
@@ -48504,7 +48743,12 @@ static PyTypeObject __pyx_type_9pywrapfst_EncodeMapper = {
   sizeof(struct __pyx_obj_9pywrapfst_EncodeMapper), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_EncodeMapper, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48557,11 +48801,14 @@ static PyTypeObject __pyx_type_9pywrapfst_EncodeMapper = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__Fst __pyx_vtable_9pywrapfst__Fst;
+static struct __pyx_vtabstruct_9pywrapfst_Fst __pyx_vtable_9pywrapfst_Fst;
 
-static PyObject *__pyx_tp_new_9pywrapfst__Fst(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst__Fst *p;
+static PyObject *__pyx_tp_new_9pywrapfst_Fst(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst_Fst *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -48569,14 +48816,14 @@ static PyObject *__pyx_tp_new_9pywrapfst__Fst(PyTypeObject *t, CYTHON_UNUSED PyO
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__Fst *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst__Fst;
+  p = ((struct __pyx_obj_9pywrapfst_Fst *)o);
+  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_Fst;
   new((void*)&(p->_fst)) std::shared_ptr<fst::script::FstClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__Fst(PyObject *o) {
-  struct __pyx_obj_9pywrapfst__Fst *p = (struct __pyx_obj_9pywrapfst__Fst *)o;
+static void __pyx_tp_dealloc_9pywrapfst_Fst(PyObject *o) {
+  struct __pyx_obj_9pywrapfst_Fst *p = (struct __pyx_obj_9pywrapfst_Fst *)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;
@@ -48586,38 +48833,46 @@ static void __pyx_tp_dealloc_9pywrapfst__Fst(PyObject *o) {
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst__Fst[] = {
-  {"_repr_svg_", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_1_repr_svg_, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst__repr_svg_},
-  {"__reduce__", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_5__reduce__, METH_NOARGS, 0},
-  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_11arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_10arc_type},
-  {"arcs", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_13arcs, METH_O, __pyx_doc_9pywrapfst_4_Fst_12arcs},
-  {"copy", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_15copy, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_14copy},
-  {"draw", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_4_Fst_17draw, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_16draw},
-  {"final", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_19final, METH_O, __pyx_doc_9pywrapfst_4_Fst_18final},
-  {"fst_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_21fst_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_20fst_type},
-  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_23input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_22input_symbols},
-  {"num_arcs", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_25num_arcs, METH_O, __pyx_doc_9pywrapfst_4_Fst_24num_arcs},
-  {"num_input_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_27num_input_epsilons, METH_O, __pyx_doc_9pywrapfst_4_Fst_26num_input_epsilons},
-  {"num_output_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_29num_output_epsilons, METH_O, __pyx_doc_9pywrapfst_4_Fst_28num_output_epsilons},
-  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_31output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_30output_symbols},
-  {"properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_4_Fst_33properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_32properties},
-  {"start", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_35start, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_34start},
-  {"states", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_37states, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_36states},
-  {"text", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_4_Fst_39text, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_4_Fst_38text},
-  {"verify", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_41verify, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_40verify},
-  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_43weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_42weight_type},
-  {"write", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_45write, METH_O, __pyx_doc_9pywrapfst_4_Fst_44write},
-  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_4_Fst_47write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_4_Fst_46write_to_string},
+static PyMethodDef __pyx_methods_9pywrapfst_Fst[] = {
+  {"_repr_svg_", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_1_repr_svg_, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst__repr_svg_},
+  {"__reduce__", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_5__reduce__, METH_NOARGS, 0},
+  {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_11arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_10arc_type},
+  {"arcs", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_13arcs, METH_O, __pyx_doc_9pywrapfst_3Fst_12arcs},
+  {"copy", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_15copy, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_14copy},
+  {"draw", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_3Fst_17draw, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_3Fst_16draw},
+  {"final", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_19final, METH_O, __pyx_doc_9pywrapfst_3Fst_18final},
+  {"fst_type", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_21fst_type, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_20fst_type},
+  {"input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_23input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_22input_symbols},
+  {"num_arcs", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_25num_arcs, METH_O, __pyx_doc_9pywrapfst_3Fst_24num_arcs},
+  {"num_input_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons, METH_O, __pyx_doc_9pywrapfst_3Fst_26num_input_epsilons},
+  {"num_output_epsilons", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons, METH_O, __pyx_doc_9pywrapfst_3Fst_28num_output_epsilons},
+  {"output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_31output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_30output_symbols},
+  {"print", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_3Fst_33print, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_3Fst_32print},
+  {"properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_3Fst_35properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_3Fst_34properties},
+  {"read", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_37read, METH_O, __pyx_doc_9pywrapfst_3Fst_36read},
+  {"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},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst__Fst = {
+static PyTypeObject __pyx_type_9pywrapfst_Fst = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._Fst", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__Fst), /*tp_basicsize*/
+  "pywrapfst.Fst", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst_Fst), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__Fst, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst_Fst, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48626,13 +48881,13 @@ static PyTypeObject __pyx_type_9pywrapfst__Fst = {
   #if PY_MAJOR_VERSION >= 3
   0, /*tp_as_async*/
   #endif
-  __pyx_pw_9pywrapfst_4_Fst_7__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_3Fst_7__repr__, /*tp_repr*/
   0, /*tp_as_number*/
   0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
-  __pyx_pw_9pywrapfst_4_Fst_9__str__, /*tp_str*/
+  __pyx_pw_9pywrapfst_3Fst_9__str__, /*tp_str*/
   0, /*tp_getattro*/
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
@@ -48644,7 +48899,7 @@ static PyTypeObject __pyx_type_9pywrapfst__Fst = {
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__Fst, /*tp_methods*/
+  __pyx_methods_9pywrapfst_Fst, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48652,9 +48907,9 @@ static PyTypeObject __pyx_type_9pywrapfst__Fst = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_4_Fst_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_3Fst_3__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__Fst, /*tp_new*/
+  __pyx_tp_new_9pywrapfst_Fst, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48670,74 +48925,82 @@ static PyTypeObject __pyx_type_9pywrapfst__Fst = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__MutableFst __pyx_vtable_9pywrapfst__MutableFst;
+static struct __pyx_vtabstruct_9pywrapfst_MutableFst __pyx_vtable_9pywrapfst_MutableFst;
 
-static PyObject *__pyx_tp_new_9pywrapfst__MutableFst(PyTypeObject *t, PyObject *a, PyObject *k) {
-  struct __pyx_obj_9pywrapfst__MutableFst *p;
-  PyObject *o = __pyx_tp_new_9pywrapfst__Fst(t, a, k);
+static PyObject *__pyx_tp_new_9pywrapfst_MutableFst(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_9pywrapfst_MutableFst *p;
+  PyObject *o = __pyx_tp_new_9pywrapfst_Fst(t, a, k);
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__MutableFst *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__Fst*)__pyx_vtabptr_9pywrapfst__MutableFst;
+  p = ((struct __pyx_obj_9pywrapfst_MutableFst *)o);
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_Fst*)__pyx_vtabptr_9pywrapfst_MutableFst;
   new((void*)&(p->_mfst)) std::shared_ptr<fst::script::MutableFstClass> ();
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__MutableFst(PyObject *o) {
-  struct __pyx_obj_9pywrapfst__MutableFst *p = (struct __pyx_obj_9pywrapfst__MutableFst *)o;
+static void __pyx_tp_dealloc_9pywrapfst_MutableFst(PyObject *o) {
+  struct __pyx_obj_9pywrapfst_MutableFst *p = (struct __pyx_obj_9pywrapfst_MutableFst *)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;
   }
   #endif
   __Pyx_call_destructor(p->_mfst);
-  __pyx_tp_dealloc_9pywrapfst__Fst(o);
-}
-
-static PyMethodDef __pyx_methods_9pywrapfst__MutableFst[] = {
-  {"add_arc", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_1add_arc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_add_arc},
-  {"add_state", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_3add_state, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_2add_state},
-  {"add_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_5add_states, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_4add_states},
-  {"arcsort", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_7arcsort, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_6arcsort},
-  {"closure", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_9closure, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_8closure},
-  {"concat", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_11concat, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_10concat},
-  {"connect", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_13connect, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_12connect},
-  {"decode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_15decode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_14decode},
-  {"delete_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_17delete_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_16delete_arcs},
-  {"delete_states", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_19delete_states, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_18delete_states},
-  {"encode", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_21encode, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_20encode},
-  {"invert", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_23invert, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_22invert},
-  {"minimize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_25minimize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_24minimize},
-  {"mutable_arcs", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_27mutable_arcs, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_26mutable_arcs},
-  {"mutable_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_29mutable_input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_28mutable_input_symbols},
-  {"mutable_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_31mutable_output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_30mutable_output_symbols},
-  {"num_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_33num_states, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_32num_states},
-  {"project", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_35project, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_34project},
-  {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_37prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_36prune},
-  {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_39push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_38push},
-  {"relabel_pairs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_41relabel_pairs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_40relabel_pairs},
-  {"relabel_tables", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_43relabel_tables, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_42relabel_tables},
-  {"reserve_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_45reserve_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_44reserve_arcs},
-  {"reserve_states", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_47reserve_states, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_46reserve_states},
-  {"reweight", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_49reweight, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_48reweight},
-  {"rmepsilon", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_51rmepsilon, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_50rmepsilon},
-  {"set_final", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_53set_final, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_52set_final},
-  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_55set_input_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_54set_input_symbols},
-  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_57set_output_symbols, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_56set_output_symbols},
-  {"set_properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_59set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_58set_properties},
-  {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_61set_start, METH_O, __pyx_doc_9pywrapfst_11_MutableFst_60set_start},
-  {"topsort", (PyCFunction)__pyx_pw_9pywrapfst_11_MutableFst_63topsort, METH_NOARGS, __pyx_doc_9pywrapfst_11_MutableFst_62topsort},
-  {"union", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_11_MutableFst_65union, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_11_MutableFst_64union},
+  __pyx_tp_dealloc_9pywrapfst_Fst(o);
+}
+
+static PyMethodDef __pyx_methods_9pywrapfst_MutableFst[] = {
+  {"add_arc", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_1add_arc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_add_arc},
+  {"add_state", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_3add_state, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_2add_state},
+  {"add_states", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_5add_states, METH_O, __pyx_doc_9pywrapfst_10MutableFst_4add_states},
+  {"arcsort", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_7arcsort, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_6arcsort},
+  {"closure", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_9closure, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_8closure},
+  {"concat", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_11concat, METH_O, __pyx_doc_9pywrapfst_10MutableFst_10concat},
+  {"connect", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_13connect, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_12connect},
+  {"decode", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_15decode, METH_O, __pyx_doc_9pywrapfst_10MutableFst_14decode},
+  {"delete_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_16delete_arcs},
+  {"delete_states", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_19delete_states, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_18delete_states},
+  {"encode", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_21encode, METH_O, __pyx_doc_9pywrapfst_10MutableFst_20encode},
+  {"invert", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_23invert, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_22invert},
+  {"minimize", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_25minimize, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_24minimize},
+  {"mutable_arcs", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs, METH_O, __pyx_doc_9pywrapfst_10MutableFst_26mutable_arcs},
+  {"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},
+  {"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},
+  {"relabel_tables", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_42relabel_tables},
+  {"reserve_arcs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_44reserve_arcs},
+  {"reserve_states", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_47reserve_states, METH_O, __pyx_doc_9pywrapfst_10MutableFst_46reserve_states},
+  {"reweight", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_49reweight, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_48reweight},
+  {"rmepsilon", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_50rmepsilon},
+  {"set_final", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_53set_final, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_52set_final},
+  {"set_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols, METH_O, __pyx_doc_9pywrapfst_10MutableFst_54set_input_symbols},
+  {"set_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols, METH_O, __pyx_doc_9pywrapfst_10MutableFst_56set_output_symbols},
+  {"set_properties", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_59set_properties, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_58set_properties},
+  {"set_start", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_61set_start, METH_O, __pyx_doc_9pywrapfst_10MutableFst_60set_start},
+  {"topsort", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_63topsort, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_62topsort},
+  {"union", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_65union, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_64union},
   {0, 0, 0, 0}
 };
 
-static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
+static PyTypeObject __pyx_type_9pywrapfst_MutableFst = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._MutableFst", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__MutableFst), /*tp_basicsize*/
+  "pywrapfst.MutableFst", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst_MutableFst), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__MutableFst, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst_MutableFst, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48747,7 +49010,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   0, /*tp_as_async*/
   #endif
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_4_Fst_7__repr__, /*tp_repr*/
+  __pyx_pw_9pywrapfst_3Fst_7__repr__, /*tp_repr*/
   #else
   0, /*tp_repr*/
   #endif
@@ -48757,7 +49020,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   0, /*tp_hash*/
   0, /*tp_call*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_4_Fst_9__str__, /*tp_str*/
+  __pyx_pw_9pywrapfst_3Fst_9__str__, /*tp_str*/
   #else
   0, /*tp_str*/
   #endif
@@ -48765,14 +49028,14 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   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  (No constructor.)\n\n  Mutable FST class, wrapping MutableFstClass.\n\n  This class extends _Fst by adding mutation operations.\n  ", /*tp_doc*/
+  "\n  (No constructor.)\n\n  Mutable FST class, wrapping MutableFstClass.\n\n  This class extends Fst by adding mutation operations.\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   0, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__MutableFst, /*tp_methods*/
+  __pyx_methods_9pywrapfst_MutableFst, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48781,12 +49044,12 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_4_Fst_3__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_3Fst_3__init__, /*tp_init*/
   #else
   0, /*tp_init*/
   #endif
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__MutableFst, /*tp_new*/
+  __pyx_tp_new_9pywrapfst_MutableFst, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48802,6 +49065,100 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFst = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
+};
+static struct __pyx_vtabstruct_9pywrapfst_VectorFst __pyx_vtable_9pywrapfst_VectorFst;
+
+static PyObject *__pyx_tp_new_9pywrapfst_VectorFst(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_9pywrapfst_VectorFst *p;
+  PyObject *o = __pyx_tp_new_9pywrapfst_MutableFst(t, a, k);
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_9pywrapfst_VectorFst *)o);
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_Fst*)__pyx_vtabptr_9pywrapfst_VectorFst;
+  return o;
+}
+
+static PyMethodDef __pyx_methods_9pywrapfst_VectorFst[] = {
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_9pywrapfst_VectorFst = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "pywrapfst.VectorFst", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst_VectorFst), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_9pywrapfst_MutableFst, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
+  0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #endif
+  #if PY_MAJOR_VERSION >= 3
+  0, /*tp_as_async*/
+  #endif
+  #if CYTHON_COMPILING_IN_PYPY
+  __pyx_pw_9pywrapfst_3Fst_7__repr__, /*tp_repr*/
+  #else
+  0, /*tp_repr*/
+  #endif
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  #if CYTHON_COMPILING_IN_PYPY
+  __pyx_pw_9pywrapfst_3Fst_9__str__, /*tp_str*/
+  #else
+  0, /*tp_str*/
+  #endif
+  0, /*tp_getattro*/
+  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  VectorFst(arc_type=\"standard\")\n\n  Constructs a concrete, empty, mutable FST.\n\n  Args:\n    arc_type: A string indicating the arc type.\n\n  Raises:\n    FstOpError: Unknown arc type.\n  ", /*tp_doc*/
+  0, /*tp_traverse*/
+  0, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_9pywrapfst_VectorFst, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_9pywrapfst_9VectorFst_1__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_9pywrapfst_VectorFst, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b1
+  0, /*tp_vectorcall*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_Arc __pyx_vtable_9pywrapfst_Arc;
 
@@ -48908,7 +49265,12 @@ static PyTypeObject __pyx_type_9pywrapfst_Arc = {
   sizeof(struct __pyx_obj_9pywrapfst_Arc), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_Arc, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -48961,6 +49323,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Arc = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator __pyx_vtable_9pywrapfst_ArcIterator;
 
@@ -49015,7 +49380,12 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   sizeof(struct __pyx_obj_9pywrapfst_ArcIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_ArcIterator, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49068,6 +49438,9 @@ static PyTypeObject __pyx_type_9pywrapfst_ArcIterator = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator __pyx_vtable_9pywrapfst_MutableArcIterator;
 
@@ -49120,7 +49493,12 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   sizeof(struct __pyx_obj_9pywrapfst_MutableArcIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_MutableArcIterator, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49173,6 +49551,9 @@ static PyTypeObject __pyx_type_9pywrapfst_MutableArcIterator = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator __pyx_vtable_9pywrapfst_StateIterator;
 
@@ -49223,7 +49604,12 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   sizeof(struct __pyx_obj_9pywrapfst_StateIterator), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_StateIterator, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49276,6 +49662,9 @@ static PyTypeObject __pyx_type_9pywrapfst_StateIterator = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_Compiler __pyx_vtable_9pywrapfst_Compiler;
 
@@ -49327,7 +49716,12 @@ static PyTypeObject __pyx_type_9pywrapfst_Compiler = {
   sizeof(struct __pyx_obj_9pywrapfst_Compiler), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_Compiler, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49380,6 +49774,9 @@ static PyTypeObject __pyx_type_9pywrapfst_Compiler = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_FarReader __pyx_vtable_9pywrapfst_FarReader;
 
@@ -49457,7 +49854,12 @@ static PyTypeObject __pyx_type_9pywrapfst_FarReader = {
   sizeof(struct __pyx_obj_9pywrapfst_FarReader), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_FarReader, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49510,6 +49912,9 @@ static PyTypeObject __pyx_type_9pywrapfst_FarReader = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 static struct __pyx_vtabstruct_9pywrapfst_FarWriter __pyx_vtable_9pywrapfst_FarWriter;
 
@@ -49573,7 +49978,12 @@ static PyTypeObject __pyx_type_9pywrapfst_FarWriter = {
   sizeof(struct __pyx_obj_9pywrapfst_FarWriter), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst_FarWriter, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49626,6 +50036,9 @@ static PyTypeObject __pyx_type_9pywrapfst_FarWriter = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 
 static struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *__pyx_freelist_9pywrapfst___pyx_scope_struct____iter__[8];
@@ -49671,7 +50084,12 @@ static PyTypeObject __pyx_type_9pywrapfst___pyx_scope_struct____iter__ = {
   sizeof(struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__), /*tp_basicsize*/
   0, /*tp_itemsize*/
   __pyx_tp_dealloc_9pywrapfst___pyx_scope_struct____iter__, /*tp_dealloc*/
+  #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
+  #endif
+  #if PY_VERSION_HEX >= 0x030800b4
+  0, /*tp_vectorcall_offset*/
+  #endif
   0, /*tp_getattr*/
   0, /*tp_setattr*/
   #if PY_MAJOR_VERSION < 3
@@ -49724,6 +50142,9 @@ static PyTypeObject __pyx_type_9pywrapfst___pyx_scope_struct____iter__ = {
   #if PY_VERSION_HEX >= 0x030800b1
   0, /*tp_vectorcall*/
   #endif
+  #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+  0, /*tp_print*/
+  #endif
 };
 
 static PyMethodDef __pyx_methods[] = {
@@ -49731,7 +50152,7 @@ static PyMethodDef __pyx_methods[] = {
   {"compact_symbol_table", (PyCFunction)__pyx_pw_9pywrapfst_11compact_symbol_table, METH_O, __pyx_doc_9pywrapfst_10compact_symbol_table},
   {"merge_symbol_table", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_13merge_symbol_table, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12merge_symbol_table},
   {"_read_EncodeMapper_from_string", (PyCFunction)__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string, METH_O, 0},
-  {"_read", (PyCFunction)__pyx_pw_9pywrapfst_17_read, METH_O, 0},
+  {"_read_Fst", (PyCFunction)__pyx_pw_9pywrapfst_17_read_Fst, METH_O, 0},
   {"_read_Fst_from_string", (PyCFunction)__pyx_pw_9pywrapfst_19_read_Fst_from_string, METH_O, 0},
   {"arcmap", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_21arcmap, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_20arcmap},
   {"compose", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_23compose, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_22compose},
@@ -49828,6 +50249,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_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_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_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},
@@ -49837,7 +50259,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_EXPANDED, __pyx_k_EXPANDED, sizeof(__pyx_k_EXPANDED), 0, 0, 1, 1},
   {&__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_EncodeMapperSymbolTable, __pyx_k_EncodeMapperSymbolTable, sizeof(__pyx_k_EncodeMapperSymbolTable), 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_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},
@@ -49852,14 +50274,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_FstSymbolTable, __pyx_k_FstSymbolTable, sizeof(__pyx_k_FstSymbolTable), 0, 0, 1, 1},
-  {&__pyx_n_s_Fst_2, __pyx_k_Fst_2, sizeof(__pyx_k_Fst_2), 0, 0, 1, 1},
-  {&__pyx_kp_u_Fst_SymbolTable_r_at_0x_x, __pyx_k_Fst_SymbolTable_r_at_0x_x, sizeof(__pyx_k_Fst_SymbolTable_r_at_0x_x), 0, 1, 0, 0},
-  {&__pyx_n_s_Fst___new, __pyx_k_Fst___new, sizeof(__pyx_k_Fst___new), 0, 0, 1, 1},
-  {&__pyx_kp_s_Fst_arc_type_standard_Construct, __pyx_k_Fst_arc_type_standard_Construct, sizeof(__pyx_k_Fst_arc_type_standard_Construct), 0, 0, 1, 0},
+  {&__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_n_s_Fst_read, __pyx_k_Fst_read, sizeof(__pyx_k_Fst_read), 0, 0, 1, 1},
-  {&__pyx_n_s_Fst_read_from_string, __pyx_k_Fst_read_from_string, sizeof(__pyx_k_Fst_read_from_string), 0, 0, 1, 1},
   {&__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},
@@ -49874,13 +50291,12 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
   {&__pyx_kp_u_Invalid_weight, __pyx_k_Invalid_weight, sizeof(__pyx_k_Invalid_weight), 0, 1, 0, 0},
   {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1},
-  {&__pyx_kp_u_Key_out_of_order, __pyx_k_Key_out_of_order, sizeof(__pyx_k_Key_out_of_order), 0, 1, 0, 0},
   {&__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_n_s_MutableFst, __pyx_k_MutableFst, sizeof(__pyx_k_MutableFst), 0, 0, 1, 1},
-  {&__pyx_n_s_MutableFstSymbolTable, __pyx_k_MutableFstSymbolTable, sizeof(__pyx_k_MutableFstSymbolTable), 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},
   {&__pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_k_NEG_TRINARY_PROPERTIES, sizeof(__pyx_k_NEG_TRINARY_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_NON_I_DETERMINISTIC, __pyx_k_NON_I_DETERMINISTIC, sizeof(__pyx_k_NON_I_DETERMINISTIC), 0, 0, 1, 1},
@@ -49930,6 +50346,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_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},
@@ -49945,7 +50362,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_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},
@@ -49964,6 +50383,7 @@ 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},
@@ -49978,13 +50398,12 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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},
-  {&__pyx_n_s_cls, __pyx_k_cls, sizeof(__pyx_k_cls), 0, 0, 1, 1},
   {&__pyx_n_s_communicate, __pyx_k_communicate, sizeof(__pyx_k_communicate), 0, 0, 1, 1},
   {&__pyx_n_s_compile, __pyx_k_compile, sizeof(__pyx_k_compile), 0, 0, 1, 1},
   {&__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_SymbolTable, __pyx_k_const_EncodeMapper_SymbolTable, sizeof(__pyx_k_const_EncodeMapper_SymbolTable), 0, 1, 0, 0},
-  {&__pyx_kp_u_const_Fst_SymbolTable_r_at_0x_x, __pyx_k_const_Fst_SymbolTable_r_at_0x_x, sizeof(__pyx_k_const_Fst_SymbolTable_r_at_0x_x), 0, 1, 0, 0},
+  {&__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_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},
@@ -50052,7 +50471,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 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},
@@ -50068,7 +50486,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_num_states, __pyx_k_num_states, sizeof(__pyx_k_num_states), 0, 0, 1, 1},
   {&__pyx_n_s_num_symbols, __pyx_k_num_symbols, sizeof(__pyx_k_num_symbols), 0, 0, 1, 1},
   {&__pyx_n_s_numbers, __pyx_k_numbers, sizeof(__pyx_k_numbers), 0, 0, 1, 1},
-  {&__pyx_n_s_object, __pyx_k_object, sizeof(__pyx_k_object), 0, 0, 1, 1},
   {&__pyx_n_s_olabel, __pyx_k_olabel, sizeof(__pyx_k_olabel), 0, 0, 1, 1},
   {&__pyx_n_s_old_isymbols, __pyx_k_old_isymbols, sizeof(__pyx_k_old_isymbols), 0, 0, 1, 1},
   {&__pyx_n_s_old_osymbols, __pyx_k_old_osymbols, sizeof(__pyx_k_old_osymbols), 0, 0, 1, 1},
@@ -50084,13 +50501,13 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_power, __pyx_k_power, sizeof(__pyx_k_power), 0, 0, 1, 1},
   {&__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},
@@ -50122,22 +50539,23 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_s_self__arc_cannot_be_converted_to, __pyx_k_self__arc_cannot_be_converted_to, sizeof(__pyx_k_self__arc_cannot_be_converted_to), 0, 0, 1, 0},
   {&__pyx_kp_s_self__fst_self__siter_cannot_be, __pyx_k_self__fst_self__siter_cannot_be, sizeof(__pyx_k_self__fst_self__siter_cannot_be), 0, 0, 1, 0},
   {&__pyx_kp_s_self__reader_cannot_be_converted, __pyx_k_self__reader_cannot_be_converted, sizeof(__pyx_k_self__reader_cannot_be_converted), 0, 0, 1, 0},
-  {&__pyx_kp_s_self__siter_self__table_cannot_b, __pyx_k_self__siter_self__table_cannot_b, sizeof(__pyx_k_self__siter_self__table_cannot_b), 0, 0, 1, 0},
+  {&__pyx_kp_s_self__siter_cannot_be_converted, __pyx_k_self__siter_cannot_be_converted, sizeof(__pyx_k_self__siter_cannot_be_converted), 0, 0, 1, 0},
   {&__pyx_kp_s_self__weight_cannot_be_converted, __pyx_k_self__weight_cannot_be_converted, sizeof(__pyx_k_self__weight_cannot_be_converted), 0, 0, 1, 0},
   {&__pyx_kp_s_self__writer_cannot_be_converted, __pyx_k_self__writer_cannot_be_converted, sizeof(__pyx_k_self__writer_cannot_be_converted), 0, 0, 1, 0},
   {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1},
   {&__pyx_n_s_set_flags, __pyx_k_set_flags, sizeof(__pyx_k_set_flags), 0, 0, 1, 1},
-  {&__pyx_n_s_set_input_symbols, __pyx_k_set_input_symbols, sizeof(__pyx_k_set_input_symbols), 0, 0, 1, 1},
   {&__pyx_n_s_set_name, __pyx_k_set_name, sizeof(__pyx_k_set_name), 0, 0, 1, 1},
-  {&__pyx_n_s_set_output_symbols, __pyx_k_set_output_symbols, sizeof(__pyx_k_set_output_symbols), 0, 0, 1, 1},
   {&__pyx_n_s_set_value, __pyx_k_set_value, sizeof(__pyx_k_set_value), 0, 0, 1, 1},
   {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1},
   {&__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_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},
@@ -50169,7 +50587,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__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_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},
@@ -50180,16 +50600,16 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {0, 0, 0, 0, 0, 0, 0}
 };
 static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 112, __pyx_L1_error)
-  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 122, __pyx_L1_error)
-  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 127, __pyx_L1_error)
-  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 132, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1344, __pyx_L1_error)
-  __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) __PYX_ERR(0, 2844, __pyx_L1_error)
-  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 356, __pyx_L1_error)
+  __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, 1160, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4480, __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)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -50220,55 +50640,66 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_self__siter_self__table_cannot_b); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __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);
 
   /* "(tree fragment)":4
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("self._siter,self._table cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
+ *     raise TypeError("self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_self__siter_self__table_cannot_b); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":1482
+  /* "pywrapfst.pyx":1516
  *   @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, 1482, __pyx_L1_error)
+  __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, 1482, __pyx_L1_error)
+  __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_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
  *     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__21 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__21);
-  __Pyx_GIVEREF(__pyx_tuple__21);
+  __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);
 
   /* "(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__22 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__22);
-  __Pyx_GIVEREF(__pyx_tuple__22);
+  __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);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50276,18 +50707,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__23 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__23);
-  __Pyx_GIVEREF(__pyx_tuple__23);
+  __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);
 
   /* "(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__24 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__24);
-  __Pyx_GIVEREF(__pyx_tuple__24);
+  __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);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50295,18 +50726,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__25 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__25);
-  __Pyx_GIVEREF(__pyx_tuple__25);
+  __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);
 
   /* "(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__26 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
+  __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);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50314,18 +50745,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__27 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__27);
-  __Pyx_GIVEREF(__pyx_tuple__27);
+  __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);
 
   /* "(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__28 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
+  __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);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50333,18 +50764,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_tuple__52 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__52);
-  __Pyx_GIVEREF(__pyx_tuple__52);
+  __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__53);
+  __Pyx_GIVEREF(__pyx_tuple__53);
 
   /* "(tree fragment)":4
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__53);
-  __Pyx_GIVEREF(__pyx_tuple__53);
+  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__54);
+  __Pyx_GIVEREF(__pyx_tuple__54);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50352,18 +50783,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__54);
-  __Pyx_GIVEREF(__pyx_tuple__54);
+  __pyx_tuple__55 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__55);
+  __Pyx_GIVEREF(__pyx_tuple__55);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__55 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__55);
-  __Pyx_GIVEREF(__pyx_tuple__55);
+  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_kp_s_self__reader_cannot_be_converted); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__56);
+  __Pyx_GIVEREF(__pyx_tuple__56);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50371,140 +50802,101 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__56);
-  __Pyx_GIVEREF(__pyx_tuple__56);
+  __pyx_tuple__57 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__57);
+  __Pyx_GIVEREF(__pyx_tuple__57);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._writer cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__57 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__57);
-  __Pyx_GIVEREF(__pyx_tuple__57);
+  __pyx_tuple__58 = PyTuple_Pack(1, __pyx_kp_s_self__writer_cannot_be_converted); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__58);
+  __Pyx_GIVEREF(__pyx_tuple__58);
 
-  /* "pywrapfst.pyx":445
+  /* "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
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_tuple__58 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(0, 445, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__58);
-  __Pyx_GIVEREF(__pyx_tuple__58);
-  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 445, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":482
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(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, 477, __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_pywrapfst_pyx, __pyx_n_s_times, 477, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 477, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":514
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(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, 509, __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_pywrapfst_pyx, __pyx_n_s_divide, 509, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 509, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":547
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_tuple__64 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 542, __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_pywrapfst_pyx, __pyx_n_s_power, 542, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":1345
+  /* "pywrapfst.pyx":1359
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __pyx_tuple__66 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 1345, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__66);
-  __Pyx_GIVEREF(__pyx_tuple__66);
-  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 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_pywrapfst_pyx, __pyx_n_s_read_from_string, 1345, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 1345, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2844
- * 
- * 
- * class Fst(object):             # <<<<<<<<<<<<<<
- * 
- *    """
- */
-  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 2844, __pyx_L1_error)
+  __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)
 
-  /* "pywrapfst.pyx":2861
- *    """
- * 
- *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     return _create_Fst(arc_type)
- * 
- */
-  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_arc_type); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 2861, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__69);
-  __Pyx_GIVEREF(__pyx_tuple__69);
-  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 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_new, 2861, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 2861, __pyx_L1_error)
-  __pyx_tuple__71 = PyTuple_Pack(1, ((PyObject*)__pyx_n_b_standard)); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 2861, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__71);
-  __Pyx_GIVEREF(__pyx_tuple__71);
-
-  /* "pywrapfst.pyx":2865
- * 
- *    @staticmethod
- *    def read(source):             # <<<<<<<<<<<<<<
- *      """
- *      read(source)
- */
-  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_source); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 2865, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__72);
-  __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read, 2865, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 2865, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2883
- * 
- *    @staticmethod
- *    def read_from_string(state):             # <<<<<<<<<<<<<<
- *      """
- *      read_from_string(state)
- */
-  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 2883, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__74);
-  __Pyx_GIVEREF(__pyx_tuple__74);
-  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 2883, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 2883, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":4056
+  /* "pywrapfst.pyx":4099
  * 
  * 
- * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__76 = 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__76)) __PYX_ERR(0, 4056, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__76);
-  __Pyx_GIVEREF(__pyx_tuple__76);
-  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4056, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 4056, __pyx_L1_error)
+  __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_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -50514,6 +50906,7 @@ 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;
@@ -50563,42 +50956,41 @@ static int __Pyx_modinit_function_export_code(void) {
   if (__Pyx_ExportFunction("_times", (void (*)(void))__pyx_f_9pywrapfst__times, "struct __pyx_obj_9pywrapfst_Weight *(struct __pyx_obj_9pywrapfst_Weight *, struct __pyx_obj_9pywrapfst_Weight *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_divide", (void (*)(void))__pyx_f_9pywrapfst__divide, "struct __pyx_obj_9pywrapfst_Weight *(struct __pyx_obj_9pywrapfst_Weight *, struct __pyx_obj_9pywrapfst_Weight *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_power", (void (*)(void))__pyx_f_9pywrapfst__power, "struct __pyx_obj_9pywrapfst_Weight *(struct __pyx_obj_9pywrapfst_Weight *, size_t)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_init_EncodeMapperSymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_EncodeMapperSymbolTable, "struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTable *(fst::SymbolTable *, std::shared_ptr<fst::script::EncodeMapperClass> )") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_init_FstSymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_FstSymbolTable, "struct __pyx_obj_9pywrapfst__FstSymbolTable *(fst::SymbolTable *, std::shared_ptr<fst::script::FstClass> )") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_init_MutableFstSymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_MutableFstSymbolTable, "struct __pyx_obj_9pywrapfst__MutableFstSymbolTable *(fst::SymbolTable *, std::shared_ptr<fst::script::MutableFstClass> )") < 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 *(fst::SymbolTable *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_init_EncodeMapperSymbolTableView", (void (*)(void))__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView, "struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(std::shared_ptr<fst::script::EncodeMapperClass> , bool)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  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("_init_EncodeMapper", (void (*)(void))__pyx_f_9pywrapfst__init_EncodeMapper, "struct __pyx_obj_9pywrapfst_EncodeMapper *(fst::script::EncodeMapperClass *)") < 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("_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("_create_Fst", (void (*)(void))__pyx_f_9pywrapfst__create_Fst, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_opt_args_9pywrapfst__create_Fst *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_read", (void (*)(void))__pyx_f_9pywrapfst__read, "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("_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("_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)
-  if (__Pyx_ExportFunction("compose", (void (*)(void))__pyx_f_9pywrapfst_compose, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("convert", (void (*)(void))__pyx_f_9pywrapfst_convert, "struct __pyx_obj_9pywrapfst__Fst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("determinize", (void (*)(void))__pyx_f_9pywrapfst_determinize, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("difference", (void (*)(void))__pyx_f_9pywrapfst_difference, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("disambiguate", (void (*)(void))__pyx_f_9pywrapfst_disambiguate, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("epsnormalize", (void (*)(void))__pyx_f_9pywrapfst_epsnormalize, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("equal", (void (*)(void))__pyx_f_9pywrapfst_equal, "bool (struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equal *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("equivalent", (void (*)(void))__pyx_f_9pywrapfst_equivalent, "bool (struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equivalent *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("intersect", (void (*)(void))__pyx_f_9pywrapfst_intersect, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("isomorphic", (void (*)(void))__pyx_f_9pywrapfst_isomorphic, "bool (struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_isomorphic *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("prune", (void (*)(void))__pyx_f_9pywrapfst_prune, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("push", (void (*)(void))__pyx_f_9pywrapfst_push, "struct __pyx_obj_9pywrapfst__MutableFst *(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("randequivalent", (void (*)(void))__pyx_f_9pywrapfst_randequivalent, "bool (struct __pyx_obj_9pywrapfst__Fst *, struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randequivalent *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  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("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)
+  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)
+  if (__Pyx_ExportFunction("compose", (void (*)(void))__pyx_f_9pywrapfst_compose, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("convert", (void (*)(void))__pyx_f_9pywrapfst_convert, "struct __pyx_obj_9pywrapfst_Fst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("determinize", (void (*)(void))__pyx_f_9pywrapfst_determinize, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("difference", (void (*)(void))__pyx_f_9pywrapfst_difference, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("disambiguate", (void (*)(void))__pyx_f_9pywrapfst_disambiguate, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("epsnormalize", (void (*)(void))__pyx_f_9pywrapfst_epsnormalize, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("equal", (void (*)(void))__pyx_f_9pywrapfst_equal, "bool (struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equal *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("equivalent", (void (*)(void))__pyx_f_9pywrapfst_equivalent, "bool (struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equivalent *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("intersect", (void (*)(void))__pyx_f_9pywrapfst_intersect, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("isomorphic", (void (*)(void))__pyx_f_9pywrapfst_isomorphic, "bool (struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_isomorphic *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("prune", (void (*)(void))__pyx_f_9pywrapfst_prune, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("push", (void (*)(void))__pyx_f_9pywrapfst_push, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("randequivalent", (void (*)(void))__pyx_f_9pywrapfst_randequivalent, "bool (struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randequivalent *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  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("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)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -50616,22 +51008,25 @@ 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, 334, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 339, __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, 334, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Weight, (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 334, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 334, __pyx_L1_error)
+  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)
   __pyx_ptype_9pywrapfst_Weight = &__pyx_type_9pywrapfst_Weight;
   __pyx_vtabptr_9pywrapfst__SymbolTable = &__pyx_vtable_9pywrapfst__SymbolTable;
-  __pyx_vtable_9pywrapfst__SymbolTable.available_key = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_available_key;
+  __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 = (__pyx_t_10basictypes_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.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;
@@ -50639,113 +51034,113 @@ static int __Pyx_modinit_type_init_code(void) {
   __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, 664, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __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, 664, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable, (PyObject *)&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 664, __pyx_L1_error)
+  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;
-  __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable = &__pyx_vtable_9pywrapfst__EncodeMapperSymbolTable;
-  __pyx_vtable_9pywrapfst__EncodeMapperSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
-  __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __pyx_L1_error)
+  __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)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_print = 0;
-  #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
-  }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTable) < 0) __PYX_ERR(0, 850, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst__EncodeMapperSymbolTable = &__pyx_type_9pywrapfst__EncodeMapperSymbolTable;
-  __pyx_vtabptr_9pywrapfst__FstSymbolTable = &__pyx_vtable_9pywrapfst__FstSymbolTable;
-  __pyx_vtable_9pywrapfst__FstSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
-  __pyx_type_9pywrapfst__FstSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __pyx_L1_error)
+  __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)
+  __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)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst__FstSymbolTable.tp_print = 0;
+  __pyx_type_9pywrapfst__FstSymbolTableView.tp_print = 0;
   #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__FstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst__FstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  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__FstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTable) < 0) __PYX_ERR(0, 870, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst__FstSymbolTable = &__pyx_type_9pywrapfst__FstSymbolTable;
+  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)
+  __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.add_symbol = (__pyx_t_10basictypes_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.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__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.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, 889, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 923, __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, 889, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 889, __pyx_L1_error)
+  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)
   __pyx_ptype_9pywrapfst__MutableSymbolTable = &__pyx_type_9pywrapfst__MutableSymbolTable;
-  __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable = &__pyx_vtable_9pywrapfst__MutableFstSymbolTable;
-  __pyx_vtable_9pywrapfst__MutableFstSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
-  __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
+  __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 PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_print = 0;
+  __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_print = 0;
   #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFstSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst__MutableFstSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  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__MutableFstSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTable) < 0) __PYX_ERR(0, 941, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst__MutableFstSymbolTable = &__pyx_type_9pywrapfst__MutableFstSymbolTable;
+  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)
+  __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, 952, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1009, __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, 952, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 952, __pyx_L1_error)
+  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)
   __pyx_ptype_9pywrapfst_SymbolTable = &__pyx_type_9pywrapfst_SymbolTable;
-  __pyx_vtabptr_9pywrapfst_SymbolTableIterator = &__pyx_vtable_9pywrapfst_SymbolTableIterator;
-  __pyx_vtable_9pywrapfst_SymbolTableIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_done;
-  __pyx_vtable_9pywrapfst_SymbolTableIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_next;
-  __pyx_vtable_9pywrapfst_SymbolTableIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_reset;
-  __pyx_vtable_9pywrapfst_SymbolTableIterator.symbol = (std::string (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_symbol;
-  __pyx_vtable_9pywrapfst_SymbolTableIterator.value = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst_SymbolTableIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19SymbolTableIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1203, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst_SymbolTableIterator.tp_print = 0;
+  __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 ((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 (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableIterator.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_SymbolTableIterator) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst_SymbolTableIterator = &__pyx_type_9pywrapfst_SymbolTableIterator;
+  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)
+  __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;
   __pyx_vtable_9pywrapfst_EncodeMapper.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_weight_type;
-  __pyx_vtable_9pywrapfst_EncodeMapper.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_flags;
-  __pyx_vtable_9pywrapfst_EncodeMapper.properties = (__pyx_t_10basictypes_uint64 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, __pyx_t_10basictypes_uint64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_properties;
+  __pyx_vtable_9pywrapfst_EncodeMapper.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_flags;
+  __pyx_vtable_9pywrapfst_EncodeMapper.properties = (uint64 (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, uint64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_properties;
   __pyx_vtable_9pywrapfst_EncodeMapper.write = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_write;
   __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__EncodeMapperSymbolTable *(*)(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__EncodeMapperSymbolTable *(*)(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 *, int __pyx_skip_dispatch))__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 *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_set_output_symbols;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
+  __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)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
   #endif
@@ -50754,7 +51149,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, 1221, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1235, __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__;
@@ -50762,167 +51157,181 @@ 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, 1221, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1221, __pyx_L1_error)
+  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)
   __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_4_Fst__local_render_svg;
-  __pyx_vtable_9pywrapfst__Fst.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_arc_type;
-  __pyx_vtable_9pywrapfst__Fst.arcs = (struct __pyx_obj_9pywrapfst_ArcIterator *(*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_arcs;
-  __pyx_vtable_9pywrapfst__Fst.copy = (struct __pyx_obj_9pywrapfst__Fst *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_copy;
-  __pyx_vtable_9pywrapfst__Fst.draw = (void (*)(struct __pyx_obj_9pywrapfst__Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_draw *__pyx_optional_args))__pyx_f_9pywrapfst_4_Fst_draw;
-  __pyx_vtable_9pywrapfst__Fst.final = (struct __pyx_obj_9pywrapfst_Weight *(*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_final;
-  __pyx_vtable_9pywrapfst__Fst.fst_type = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_fst_type;
-  __pyx_vtable_9pywrapfst__Fst.input_symbols = (struct __pyx_obj_9pywrapfst__FstSymbolTable *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_input_symbols;
-  __pyx_vtable_9pywrapfst__Fst.num_arcs = (size_t (*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_num_arcs;
-  __pyx_vtable_9pywrapfst__Fst.num_input_epsilons = (size_t (*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_num_input_epsilons;
-  __pyx_vtable_9pywrapfst__Fst.num_output_epsilons = (size_t (*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_num_output_epsilons;
-  __pyx_vtable_9pywrapfst__Fst.output_symbols = (struct __pyx_obj_9pywrapfst__FstSymbolTable *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_output_symbols;
-  __pyx_vtable_9pywrapfst__Fst.properties = (__pyx_t_10basictypes_uint64 (*)(struct __pyx_obj_9pywrapfst__Fst *, __pyx_t_10basictypes_uint64, bool, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_properties;
-  __pyx_vtable_9pywrapfst__Fst.start = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_start;
-  __pyx_vtable_9pywrapfst__Fst.states = (struct __pyx_obj_9pywrapfst_StateIterator *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_states;
-  __pyx_vtable_9pywrapfst__Fst.text = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_4_Fst_text *__pyx_optional_args))__pyx_f_9pywrapfst_4_Fst_text;
-  __pyx_vtable_9pywrapfst__Fst.verify = (bool (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_verify;
-  __pyx_vtable_9pywrapfst__Fst.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_weight_type;
-  __pyx_vtable_9pywrapfst__Fst.write = (void (*)(struct __pyx_obj_9pywrapfst__Fst *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_write;
-  __pyx_vtable_9pywrapfst__Fst.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst__Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_4_Fst_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1467, __pyx_L1_error)
+  __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;
+  __pyx_vtable_9pywrapfst_Fst.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_arc_type;
+  __pyx_vtable_9pywrapfst_Fst.arcs = (struct __pyx_obj_9pywrapfst_ArcIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_arcs;
+  __pyx_vtable_9pywrapfst_Fst.copy = (struct __pyx_obj_9pywrapfst_Fst *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_copy;
+  __pyx_vtable_9pywrapfst_Fst.draw = (void (*)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args))__pyx_f_9pywrapfst_3Fst_draw;
+  __pyx_vtable_9pywrapfst_Fst.final = (struct __pyx_obj_9pywrapfst_Weight *(*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_final;
+  __pyx_vtable_9pywrapfst_Fst.fst_type = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_fst_type;
+  __pyx_vtable_9pywrapfst_Fst.input_symbols = (struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_input_symbols;
+  __pyx_vtable_9pywrapfst_Fst.num_arcs = (size_t (*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_num_arcs;
+  __pyx_vtable_9pywrapfst_Fst.num_input_epsilons = (size_t (*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_num_input_epsilons;
+  __pyx_vtable_9pywrapfst_Fst.num_output_epsilons = (size_t (*)(struct __pyx_obj_9pywrapfst_Fst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_num_output_epsilons;
+  __pyx_vtable_9pywrapfst_Fst.output_symbols = (struct __pyx_obj_9pywrapfst__FstSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_output_symbols;
+  __pyx_vtable_9pywrapfst_Fst.print = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args))__pyx_f_9pywrapfst_3Fst_print;
+  __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 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)
+  __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;
+  __pyx_vtable_9pywrapfst_MutableFst._check_mutating_imethod = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod;
+  __pyx_vtable_9pywrapfst_MutableFst._add_arc = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_obj_9pywrapfst_Arc *))__pyx_f_9pywrapfst_10MutableFst__add_arc;
+  __pyx_vtable_9pywrapfst_MutableFst.add_state = (int64 (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_add_state;
+  __pyx_vtable_9pywrapfst_MutableFst.add_states = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_add_states;
+  __pyx_vtable_9pywrapfst_MutableFst._arcsort = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__arcsort;
+  __pyx_vtable_9pywrapfst_MutableFst._closure = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__closure *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__closure;
+  __pyx_vtable_9pywrapfst_MutableFst._concat = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_Fst *))__pyx_f_9pywrapfst_10MutableFst__concat;
+  __pyx_vtable_9pywrapfst_MutableFst._connect = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__connect;
+  __pyx_vtable_9pywrapfst_MutableFst._decode = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *))__pyx_f_9pywrapfst_10MutableFst__decode;
+  __pyx_vtable_9pywrapfst_MutableFst._delete_arcs = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__delete_arcs;
+  __pyx_vtable_9pywrapfst_MutableFst._delete_states = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__delete_states;
+  __pyx_vtable_9pywrapfst_MutableFst._encode = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *))__pyx_f_9pywrapfst_10MutableFst__encode;
+  __pyx_vtable_9pywrapfst_MutableFst._invert = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__invert;
+  __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._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;
+  __pyx_vtable_9pywrapfst_MutableFst._relabel_tables = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__relabel_tables;
+  __pyx_vtable_9pywrapfst_MutableFst._reserve_arcs = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, size_t))__pyx_f_9pywrapfst_10MutableFst__reserve_arcs;
+  __pyx_vtable_9pywrapfst_MutableFst._reserve_states = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64))__pyx_f_9pywrapfst_10MutableFst__reserve_states;
+  __pyx_vtable_9pywrapfst_MutableFst._reweight = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *, struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__reweight;
+  __pyx_vtable_9pywrapfst_MutableFst._rmepsilon = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__rmepsilon;
+  __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._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 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, 1467, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst__Fst) < 0) __PYX_ERR(0, 1467, __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;
-  __pyx_vtable_9pywrapfst__MutableFst._check_mutating_imethod = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__check_mutating_imethod;
-  __pyx_vtable_9pywrapfst__MutableFst._add_arc = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_obj_9pywrapfst_Arc *))__pyx_f_9pywrapfst_11_MutableFst__add_arc;
-  __pyx_vtable_9pywrapfst__MutableFst.add_state = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_add_state;
-  __pyx_vtable_9pywrapfst__MutableFst.add_states = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_add_states;
-  __pyx_vtable_9pywrapfst__MutableFst._arcsort = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__arcsort *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__arcsort;
-  __pyx_vtable_9pywrapfst__MutableFst._closure = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__closure *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__closure;
-  __pyx_vtable_9pywrapfst__MutableFst._concat = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__Fst *))__pyx_f_9pywrapfst_11_MutableFst__concat;
-  __pyx_vtable_9pywrapfst__MutableFst._connect = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__connect;
-  __pyx_vtable_9pywrapfst__MutableFst._decode = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *))__pyx_f_9pywrapfst_11_MutableFst__decode;
-  __pyx_vtable_9pywrapfst__MutableFst._delete_arcs = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_arcs *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__delete_arcs;
-  __pyx_vtable_9pywrapfst__MutableFst._delete_states = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__delete_states *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__delete_states;
-  __pyx_vtable_9pywrapfst__MutableFst._encode = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst_EncodeMapper *))__pyx_f_9pywrapfst_11_MutableFst__encode;
-  __pyx_vtable_9pywrapfst__MutableFst._invert = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__invert;
-  __pyx_vtable_9pywrapfst__MutableFst._minimize = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__minimize *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__minimize;
-  __pyx_vtable_9pywrapfst__MutableFst.mutable_arcs = (struct __pyx_obj_9pywrapfst_MutableArcIterator *(*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_mutable_arcs;
-  __pyx_vtable_9pywrapfst__MutableFst.num_states = (__pyx_t_10basictypes_int64 (*)(struct __pyx_obj_9pywrapfst__MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11_MutableFst_num_states;
-  __pyx_vtable_9pywrapfst__MutableFst._project = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__project *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__project;
-  __pyx_vtable_9pywrapfst__MutableFst._prune = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__prune *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__prune;
-  __pyx_vtable_9pywrapfst__MutableFst._push = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__push *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__push;
-  __pyx_vtable_9pywrapfst__MutableFst._relabel_pairs = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_pairs *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__relabel_pairs;
-  __pyx_vtable_9pywrapfst__MutableFst._relabel_tables = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__relabel_tables *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__relabel_tables;
-  __pyx_vtable_9pywrapfst__MutableFst._reserve_arcs = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, size_t))__pyx_f_9pywrapfst_11_MutableFst__reserve_arcs;
-  __pyx_vtable_9pywrapfst__MutableFst._reserve_states = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64))__pyx_f_9pywrapfst_11_MutableFst__reserve_states;
-  __pyx_vtable_9pywrapfst__MutableFst._reweight = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, PyObject *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__reweight *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__reweight;
-  __pyx_vtable_9pywrapfst__MutableFst._rmepsilon = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_opt_args_9pywrapfst_11_MutableFst__rmepsilon *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__rmepsilon;
-  __pyx_vtable_9pywrapfst__MutableFst._set_final = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64, struct __pyx_opt_args_9pywrapfst_11_MutableFst__set_final *__pyx_optional_args))__pyx_f_9pywrapfst_11_MutableFst__set_final;
-  __pyx_vtable_9pywrapfst__MutableFst._set_properties = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_uint64, __pyx_t_10basictypes_uint64))__pyx_f_9pywrapfst_11_MutableFst__set_properties;
-  __pyx_vtable_9pywrapfst__MutableFst._set_start = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, __pyx_t_10basictypes_int64))__pyx_f_9pywrapfst_11_MutableFst__set_start;
-  __pyx_vtable_9pywrapfst__MutableFst._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_11_MutableFst__set_input_symbols;
-  __pyx_vtable_9pywrapfst__MutableFst._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_11_MutableFst__set_output_symbols;
-  __pyx_vtable_9pywrapfst__MutableFst._topsort = (void (*)(struct __pyx_obj_9pywrapfst__MutableFst *))__pyx_f_9pywrapfst_11_MutableFst__topsort;
-  __pyx_type_9pywrapfst__MutableFst.tp_base = __pyx_ptype_9pywrapfst__Fst;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __pyx_L1_error)
+  __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)
+  __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 PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst__MutableFst.tp_print = 0;
+  __pyx_type_9pywrapfst_VectorFst.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 ((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__MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst__MutableFst) < 0) __PYX_ERR(0, 1888, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst__MutableFst = &__pyx_type_9pywrapfst__MutableFst;
+  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)
+  __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, 2995, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3039, __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, 2995, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
+  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)
   __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;
-  __pyx_vtable_9pywrapfst_ArcIterator.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_flags;
+  __pyx_vtable_9pywrapfst_ArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_flags;
   __pyx_vtable_9pywrapfst_ArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_next;
   __pyx_vtable_9pywrapfst_ArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_position;
   __pyx_vtable_9pywrapfst_ArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_reset;
   __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 *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_set_flags;
+  __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, 3062, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3106, __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, 3062, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
+  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)
   __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;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.flags = (__pyx_t_10basictypes_uint8 (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_flags;
+  __pyx_vtable_9pywrapfst_MutableArcIterator.flags = (uint8 (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_flags;
   __pyx_vtable_9pywrapfst_MutableArcIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_next;
   __pyx_vtable_9pywrapfst_MutableArcIterator.position = (size_t (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_position;
   __pyx_vtable_9pywrapfst_MutableArcIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_reset;
   __pyx_vtable_9pywrapfst_MutableArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_seek;
-  __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, __pyx_t_10basictypes_uint8, __pyx_t_10basictypes_uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_flags;
+  __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, 3173, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3217, __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, 3173, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3173, __pyx_L1_error)
+  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)
   __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 = (__pyx_t_10basictypes_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, 3293, __pyx_L1_error)
+  __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 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, 3293, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3293, __pyx_L1_error)
+  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)
   __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.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, 4199, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4242, __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, 4199, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4199, __pyx_L1_error)
+  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)
   __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;
@@ -50930,39 +51339,39 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarReader.error = (bool (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_error;
   __pyx_vtable_9pywrapfst_FarReader.far_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_far_type;
   __pyx_vtable_9pywrapfst_FarReader.find = (bool (*)(struct __pyx_obj_9pywrapfst_FarReader *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_find;
-  __pyx_vtable_9pywrapfst_FarReader.get_fst = (struct __pyx_obj_9pywrapfst__Fst *(*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_get_fst;
+  __pyx_vtable_9pywrapfst_FarReader.get_fst = (struct __pyx_obj_9pywrapfst_Fst *(*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_get_fst;
   __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, 4336, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4379, __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, 4336, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4336, __pyx_L1_error)
+  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)
   __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;
   __pyx_vtable_9pywrapfst_FarWriter.close = (void (*)(struct __pyx_obj_9pywrapfst_FarWriter *))__pyx_f_9pywrapfst_9FarWriter_close;
-  __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.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, 4483, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4525, __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, 4483, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4483, __pyx_L1_error)
+  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)
   __pyx_ptype_9pywrapfst_FarWriter = &__pyx_type_9pywrapfst_FarWriter;
-  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3193, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3237, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_print = 0;
   #endif
@@ -51202,76 +51611,105 @@ if (!__Pyx_RefNanny) {
   if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   #endif
 
-  /* "pywrapfst.pyx":98
+  /* "pywrapfst.pyx":99
  * 
  * # Python imports.
+ * import logging             # <<<<<<<<<<<<<<
+ * import numbers
+ * import subprocess
+ */
+  __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);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) __PYX_ERR(0, 99, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":100
+ * # Python imports.
+ * import logging
  * import numbers             # <<<<<<<<<<<<<<
  * import subprocess
  * 
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numbers, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error)
+  __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);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numbers, __pyx_t_1) < 0) __PYX_ERR(0, 98, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_numbers, __pyx_t_1) < 0) __PYX_ERR(0, 100, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":99
- * # Python imports.
+  /* "pywrapfst.pyx":101
+ * import logging
  * import numbers
  * import subprocess             # <<<<<<<<<<<<<<
  * 
- * import logging
+ * # TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 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, 99, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_subprocess, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":101
- * import subprocess
+  /* "pywrapfst.pyx":104
  * 
- * import logging             # <<<<<<<<<<<<<<
+ * # TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
+ * import warnings             # <<<<<<<<<<<<<<
+ * 
+ * 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_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) __PYX_ERR(0, 104, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pywrapfst.pyx":106
+ * import warnings
+ * 
+ * warnings.simplefilter("always", DeprecationWarning)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_warnings); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __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);
+  __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)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":107
+  /* "pywrapfst.pyx":112
  * 
  * 
  * class FstError(Exception):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __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, 107, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 112, __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, 107, __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, 112, __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, 107, __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, 112, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 107, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 112, __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":112
+  /* "pywrapfst.pyx":117
  * 
  * 
  * class FstArgError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -51279,28 +51717,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, 112, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __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, 112, __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, 117, __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, 112, __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, 117, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 112, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 117, __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":117
+  /* "pywrapfst.pyx":122
  * 
  * 
  * class FstBadWeightError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 122, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 122, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
@@ -51308,28 +51746,28 @@ 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, 117, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 122, __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, 117, __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, 122, __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, 117, __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, 122, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 117, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 122, __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":122
+  /* "pywrapfst.pyx":127
  * 
  * 
  * class FstDeletedConstructorError(FstError, RuntimeError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -51337,28 +51775,28 @@ if (!__Pyx_RefNanny) {
   __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, 122, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __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, 122, __pyx_L1_error)
+  __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_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, 122, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstDeletedConstructorError, __pyx_t_4) < 0) __PYX_ERR(0, 122, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstDeletedConstructorError, __pyx_t_4) < 0) __PYX_ERR(0, 127, __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":127
+  /* "pywrapfst.pyx":132
  * 
  * 
  * class FstIndexError(FstError, IndexError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
@@ -51366,28 +51804,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_IndexError);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_IndexError);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __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, 127, __pyx_L1_error)
+  __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_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, 127, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIndexError, __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, 132, __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":132
+  /* "pywrapfst.pyx":137
  * 
  * 
  * class FstIOError(FstError, IOError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 137, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -51395,28 +51833,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_IOError);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_IOError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __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, 132, __pyx_L1_error)
+  __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_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, 132, __pyx_L1_error)
+  __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_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIOError, __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, 137, __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":137
+  /* "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, 137, __pyx_L1_error)
+  __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, 137, __pyx_L1_error)
+  __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);
@@ -51424,1700 +51862,1671 @@ if (!__Pyx_RefNanny) {
   __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, 137, __pyx_L1_error)
+  __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, 137, __pyx_L1_error)
+  __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, 137, __pyx_L1_error)
+  __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, 137, __pyx_L1_error)
+  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":392
+  /* "pywrapfst.pyx":397
  * 
  *   @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, 392, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":391
+  /* "pywrapfst.pyx":396
  *   # 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, 391, __pyx_L1_error)
+  __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, 392, __pyx_L1_error)
+  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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":401
+  /* "pywrapfst.pyx":406
  * 
  *   @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, 401, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":400
+  /* "pywrapfst.pyx":405
  *     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, 400, __pyx_L1_error)
+  __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, 401, __pyx_L1_error)
+  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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":410
+  /* "pywrapfst.pyx":415
  * 
  *   @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, 410, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":409
+  /* "pywrapfst.pyx":414
  *     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, 409, __pyx_L1_error)
+  __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, 410, __pyx_L1_error)
+  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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":450
  * 
  * 
  * 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, 445, __pyx_L1_error)
+  __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, 445, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":482
  * 
  * 
  * 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, 477, __pyx_L1_error)
+  __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, 477, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":514
  * 
  * 
  * 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, 509, __pyx_L1_error)
+  __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, 509, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":547
  * 
  * 
  * 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, 542, __pyx_L1_error)
+  __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, 542, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":900
- *   """
+  /* "pywrapfst.pyx":952
+ *     return mutable_raw
  * 
- *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):             # <<<<<<<<<<<<<<
+ *   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;
 
-  /* "pywrapfst.pyx":977
+  /* "pywrapfst.pyx":1036
  * 
  *   @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, 977, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":976
- *     self._smart_table.reset(self._table)
+  /* "pywrapfst.pyx":1035
+ *     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, 976, __pyx_L1_error)
+  __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, 977, __pyx_L1_error)
+  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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":998
+  /* "pywrapfst.pyx":1057
  * 
  *   @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, 998, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":997
- *     return _init_SymbolTable(syms.release())
+  /* "pywrapfst.pyx":1056
+ *     return _init_SymbolTable(move(syms))
  * 
  *   @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, 997, __pyx_L1_error)
+  __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, 998, __pyx_L1_error)
+  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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1023
+  /* "pywrapfst.pyx":1082
  * 
  *   @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, 1023, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":1022
- *     return _init_SymbolTable(syms.release())
+  /* "pywrapfst.pyx":1081
+ *     return _init_SymbolTable(move(syms))
  * 
  *   @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, 1022, __pyx_L1_error)
+  __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, 1023, __pyx_L1_error)
+  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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1323
+  /* "pywrapfst.pyx":1337
  * 
  *   @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, 1323, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":1322
+  /* "pywrapfst.pyx":1336
  *     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, 1322, __pyx_L1_error)
+  __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, 1323, __pyx_L1_error)
+  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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1345
+  /* "pywrapfst.pyx":1359
  * 
  *   @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, 1345, __pyx_L1_error)
+  __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, 1345, __pyx_L1_error)
+  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;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1344
+  /* "pywrapfst.pyx":1358
  *     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, 1345, __pyx_L1_error)
+  __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, 1344, __pyx_L1_error)
+  __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_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, 1345, __pyx_L1_error)
+  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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":2176
- *     return self
+  /* "pywrapfst.pyx":1844
  * 
- *   cdef void _minimize(self, float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *   @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);
+
+  /* "pywrapfst.pyx":1843
+ *     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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
+
+  /* "pywrapfst.pyx":1862
+ * 
+ *   @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);
+
+  /* "pywrapfst.pyx":1861
+ *     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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
+
+  /* "pywrapfst.pyx":2273
+ * 
+ *   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__9 = fst::kShortestDelta;
+  __pyx_k__10 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2182
+  /* "pywrapfst.pyx":2279
  *     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__10 = fst::kShortestDelta;
+  __pyx_k__11 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2278
- *     return self
+  /* "pywrapfst.pyx":2375
  * 
- *   cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *   cdef void _prune(self,
+ *                    float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                    int64 nstate=fst.kNoStateId,
+ *                    weight=None) except *:
+ */
+  __pyx_k__12 = fst::kDelta;
+
+  /* "pywrapfst.pyx":2376
+ *   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__11 = fst::kDelta;
-  __pyx_k__12 = fst::kNoStateId;
+  __pyx_k__13 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2287
+  /* "pywrapfst.pyx":2385
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):
  */
-  __pyx_k__13 = fst::kDelta;
+  __pyx_k__14 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2288
+  /* "pywrapfst.pyx":2386
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *             weight=None):
  *     """
  */
-  __pyx_k__14 = fst::kNoStateId;
+  __pyx_k__15 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2313
+  /* "pywrapfst.pyx":2411
  * 
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                   bool remove_total_weight=False,
- *                   bool to_final=False) except *:
+ *                   bool to_final=False):
  */
-  __pyx_k__15 = fst::kShortestDelta;
+  __pyx_k__16 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2321
+  /* "pywrapfst.pyx":2418
  * 
  *   def push(self,
  *            float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *            bool remove_total_weight=False,
  *            bool to_final=False):
  */
-  __pyx_k__16 = fst::kShortestDelta;
+  __pyx_k__17 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2560
+  /* "pywrapfst.pyx":2656
  *                        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(),
  */
-  __pyx_k__17 = fst::kNoStateId;
+  __pyx_k__18 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2561
+  /* "pywrapfst.pyx":2657
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:             # <<<<<<<<<<<<<<
  *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
  *                                                        weight)
  */
-  __pyx_k__18 = fst::kShortestDelta;
+  __pyx_k__19 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2577
+  /* "pywrapfst.pyx":2673
  *                 bool connect=True,
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                 float delta=fst.kShortestDelta):
  *     """
  */
-  __pyx_k__19 = fst::kNoStateId;
+  __pyx_k__20 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2578
+  /* "pywrapfst.pyx":2674
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
  *                 float delta=fst.kShortestDelta):             # <<<<<<<<<<<<<<
  *     """
  *     rmepsilon(self, queue_type="auto", connect=True, weight=None,
  */
-  __pyx_k__20 = fst::kShortestDelta;
-
-  /* "pywrapfst.pyx":2844
- * 
- * 
- * class Fst(object):             # <<<<<<<<<<<<<<
- * 
- *    """
- */
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_tuple__68); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2844, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_tuple__68, __pyx_n_s_Fst_2, __pyx_n_s_Fst_2, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, __pyx_kp_s_Fst_arc_type_standard_Construct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2844, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_k__21 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2861
- *    """
- * 
- *    def __new__(cls, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     return _create_Fst(arc_type)
- * 
- */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_1__new__, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst___new, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2861, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__71);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_new, __pyx_t_3) < 0) __PYX_ERR(0, 2861, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-
-  /* "pywrapfst.pyx":2865
- * 
- *    @staticmethod
- *    def read(source):             # <<<<<<<<<<<<<<
- *      """
- *      read(source)
- */
-  __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_3read, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2865, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-
-  /* "pywrapfst.pyx":2864
- *     return _create_Fst(arc_type)
- * 
- *    @staticmethod             # <<<<<<<<<<<<<<
- *    def read(source):
- *      """
- */
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2864, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read, __pyx_t_4) < 0) __PYX_ERR(0, 2865, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-
-  /* "pywrapfst.pyx":2883
- * 
- *    @staticmethod
- *    def read_from_string(state):             # <<<<<<<<<<<<<<
- *      """
- *      read_from_string(state)
- */
-  __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_9pywrapfst_3Fst_5read_from_string, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_Fst_read_from_string, NULL, __pyx_n_s_pywrapfst_2, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2883, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-
-  /* "pywrapfst.pyx":2882
- *      return _read(source)
- * 
- *    @staticmethod             # <<<<<<<<<<<<<<
- *    def read_from_string(state):
- *      """
- */
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2882, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_read_from_string, __pyx_t_3) < 0) __PYX_ERR(0, 2883, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-
-  /* "pywrapfst.pyx":2844
- * 
- * 
- * class Fst(object):             # <<<<<<<<<<<<<<
- * 
- *    """
- */
-  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Fst_2, __pyx_tuple__68, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2844, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Fst_2, __pyx_t_3) < 0) __PYX_ERR(0, 2844, __pyx_L1_error)
-  __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":2904
+  /* "pywrapfst.pyx":2948
  * 
  * 
  * 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, 2904, __pyx_L1_error)
+  __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, 2904, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2905
+  /* "pywrapfst.pyx":2949
  * 
  * 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, 2905, __pyx_L1_error)
+  __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, 2905, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2906
+  /* "pywrapfst.pyx":2950
  * 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, 2906, __pyx_L1_error)
+  __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, 2906, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2912
+  /* "pywrapfst.pyx":2956
  * 
  * 
  * 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, 2912, __pyx_L1_error)
+  __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, 2912, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2913
+  /* "pywrapfst.pyx":2957
  * 
  * 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, 2913, __pyx_L1_error)
+  __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, 2913, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2914
+  /* "pywrapfst.pyx":2958
  * 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, 2914, __pyx_L1_error)
+  __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, 2914, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2915
+  /* "pywrapfst.pyx":2959
  * 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, 2915, __pyx_L1_error)
+  __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, 2915, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2916
+  /* "pywrapfst.pyx":2960
  * 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, 2916, __pyx_L1_error)
+  __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, 2916, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2917
+  /* "pywrapfst.pyx":2961
  * 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, 2917, __pyx_L1_error)
+  __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, 2917, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2918
+  /* "pywrapfst.pyx":2962
  * 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, 2918, __pyx_L1_error)
+  __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, 2918, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2919
+  /* "pywrapfst.pyx":2963
  * 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, 2919, __pyx_L1_error)
+  __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, 2919, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2920
+  /* "pywrapfst.pyx":2964
  * 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, 2920, __pyx_L1_error)
+  __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, 2920, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2921
+  /* "pywrapfst.pyx":2965
  * 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, 2921, __pyx_L1_error)
+  __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, 2921, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2922
+  /* "pywrapfst.pyx":2966
  * 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, 2922, __pyx_L1_error)
+  __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, 2922, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2923
+  /* "pywrapfst.pyx":2967
  * 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, 2923, __pyx_L1_error)
+  __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, 2923, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2924
+  /* "pywrapfst.pyx":2968
  * 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, 2924, __pyx_L1_error)
+  __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, 2924, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2925
+  /* "pywrapfst.pyx":2969
  * 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, 2925, __pyx_L1_error)
+  __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, 2925, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2926
+  /* "pywrapfst.pyx":2970
  * 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, 2926, __pyx_L1_error)
+  __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, 2926, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2927
+  /* "pywrapfst.pyx":2971
  * 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, 2927, __pyx_L1_error)
+  __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, 2927, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2928
+  /* "pywrapfst.pyx":2972
  * 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, 2928, __pyx_L1_error)
+  __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, 2928, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2929
+  /* "pywrapfst.pyx":2973
  * 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, 2929, __pyx_L1_error)
+  __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, 2929, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2930
+  /* "pywrapfst.pyx":2974
  * 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, 2930, __pyx_L1_error)
+  __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, 2930, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2931
+  /* "pywrapfst.pyx":2975
  * 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, 2931, __pyx_L1_error)
+  __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, 2931, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2932
+  /* "pywrapfst.pyx":2976
  * 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, 2932, __pyx_L1_error)
+  __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, 2932, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2933
+  /* "pywrapfst.pyx":2977
  * 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, 2933, __pyx_L1_error)
+  __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, 2933, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2934
+  /* "pywrapfst.pyx":2978
  * 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, 2934, __pyx_L1_error)
+  __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, 2934, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2935
+  /* "pywrapfst.pyx":2979
  * 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, 2935, __pyx_L1_error)
+  __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, 2935, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2936
+  /* "pywrapfst.pyx":2980
  * 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, 2936, __pyx_L1_error)
+  __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, 2936, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2937
+  /* "pywrapfst.pyx":2981
  * 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, 2937, __pyx_L1_error)
+  __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, 2937, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2938
+  /* "pywrapfst.pyx":2982
  * 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, 2938, __pyx_L1_error)
+  __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, 2938, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2939
+  /* "pywrapfst.pyx":2983
  * 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, 2939, __pyx_L1_error)
+  __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, 2939, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2940
+  /* "pywrapfst.pyx":2984
  * 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, 2940, __pyx_L1_error)
+  __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, 2940, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2941
+  /* "pywrapfst.pyx":2985
  * 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, 2941, __pyx_L1_error)
+  __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, 2941, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2942
+  /* "pywrapfst.pyx":2986
  * 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, 2942, __pyx_L1_error)
+  __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, 2942, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2943
+  /* "pywrapfst.pyx":2987
  * 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, 2943, __pyx_L1_error)
+  __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, 2943, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2944
+  /* "pywrapfst.pyx":2988
  * 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, 2944, __pyx_L1_error)
+  __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, 2944, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2945
+  /* "pywrapfst.pyx":2989
  * 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, 2945, __pyx_L1_error)
+  __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, 2945, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2946
+  /* "pywrapfst.pyx":2990
  * 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, 2946, __pyx_L1_error)
+  __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, 2946, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2947
+  /* "pywrapfst.pyx":2991
  * 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, 2947, __pyx_L1_error)
+  __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, 2947, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2948
+  /* "pywrapfst.pyx":2992
  * 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, 2948, __pyx_L1_error)
+  __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, 2948, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2949
+  /* "pywrapfst.pyx":2993
  * 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, 2949, __pyx_L1_error)
+  __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, 2949, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2950
+  /* "pywrapfst.pyx":2994
  * 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, 2950, __pyx_L1_error)
+  __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, 2950, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2951
+  /* "pywrapfst.pyx":2995
  * 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, 2951, __pyx_L1_error)
+  __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, 2951, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2952
+  /* "pywrapfst.pyx":2996
  * 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, 2952, __pyx_L1_error)
+  __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, 2952, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2953
+  /* "pywrapfst.pyx":2997
  * 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, 2953, __pyx_L1_error)
+  __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, 2953, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2954
+  /* "pywrapfst.pyx":2998
  * 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, 2954, __pyx_L1_error)
+  __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, 2954, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2955
+  /* "pywrapfst.pyx":2999
  * 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, 2955, __pyx_L1_error)
+  __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, 2955, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2956
+  /* "pywrapfst.pyx":3000
  * 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, 2956, __pyx_L1_error)
+  __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, 2956, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2957
+  /* "pywrapfst.pyx":3001
  * 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, 2957, __pyx_L1_error)
+  __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, 2957, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2958
+  /* "pywrapfst.pyx":3002
  * 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, 2958, __pyx_L1_error)
+  __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, 2958, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2959
+  /* "pywrapfst.pyx":3003
  * 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, 2959, __pyx_L1_error)
+  __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, 2959, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2960
+  /* "pywrapfst.pyx":3004
  * 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, 2960, __pyx_L1_error)
+  __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, 2960, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2961
+  /* "pywrapfst.pyx":3005
  * 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, 2961, __pyx_L1_error)
+  __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, 2961, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2962
+  /* "pywrapfst.pyx":3006
  * 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, 2962, __pyx_L1_error)
+  __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, 2962, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2963
+  /* "pywrapfst.pyx":3007
  * 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, 2963, __pyx_L1_error)
+  __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, 2963, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2964
+  /* "pywrapfst.pyx":3008
  * 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, 2964, __pyx_L1_error)
+  __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, 2964, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2965
+  /* "pywrapfst.pyx":3009
  * 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, 2965, __pyx_L1_error)
+  __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, 2965, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2966
+  /* "pywrapfst.pyx":3010
  * 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, 2966, __pyx_L1_error)
+  __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, 2966, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2967
+  /* "pywrapfst.pyx":3011
  * 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, 2967, __pyx_L1_error)
+  __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, 2967, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2968
+  /* "pywrapfst.pyx":3012
  * 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, 2968, __pyx_L1_error)
+  __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, 2968, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2969
+  /* "pywrapfst.pyx":3013
  * 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, 2969, __pyx_L1_error)
+  __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, 2969, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2975
+  /* "pywrapfst.pyx":3019
  * 
  * 
  * 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, 2975, __pyx_L1_error)
+  __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, 2975, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2976
+  /* "pywrapfst.pyx":3020
  * 
  * 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, 2976, __pyx_L1_error)
+  __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, 2976, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":3021
  * 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, 2977, __pyx_L1_error)
+  __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, 2977, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2978
+  /* "pywrapfst.pyx":3022
  * 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, 2978, __pyx_L1_error)
+  __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, 2978, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2979
+  /* "pywrapfst.pyx":3023
  * 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, 2979, __pyx_L1_error)
+  __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, 2979, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2980
+  /* "pywrapfst.pyx":3024
  * 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, 2980, __pyx_L1_error)
+  __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, 2980, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2981
+  /* "pywrapfst.pyx":3025
  * 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, 2981, __pyx_L1_error)
+  __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, 2981, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2987
+  /* "pywrapfst.pyx":3031
  * 
  * 
  * 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, 2987, __pyx_L1_error)
+  __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, 2987, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2988
+  /* "pywrapfst.pyx":3032
  * 
  * 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, 2988, __pyx_L1_error)
+  __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, 2988, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":2989
+  /* "pywrapfst.pyx":3033
  * 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, 2989, __pyx_L1_error)
+  __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, 2989, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":3361
+  /* "pywrapfst.pyx":3405
  * 
- * cdef _Fst _map(_Fst ifst,
+ * cdef Fst _map(Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                map_type=b"identity",
  *                double power=1.,
  */
-  __pyx_k__29 = fst::kDelta;
+  __pyx_k__30 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3377
+  /* "pywrapfst.pyx":3421
  * 
- * cpdef _Fst arcmap(_Fst ifst,
- *                   float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                   map_type=b"identity",
- *                   double power=1.,
+ * cpdef Fst arcmap(Fst ifst,
+ *                  float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                  map_type=b"identity",
+ *                  double power=1.,
  */
-  __pyx_k__30 = fst::kDelta;
+  __pyx_k__31 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3376
+  /* "pywrapfst.pyx":3420
  * 
  * 
- * cpdef _Fst arcmap(_Fst ifst,             # <<<<<<<<<<<<<<
- *                   float delta=fst.kDelta,
- *                   map_type=b"identity",
+ * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
+ *                  float delta=fst.kDelta,
+ *                  map_type=b"identity",
  */
-  __pyx_k__30 = fst::kDelta;
+  __pyx_k__31 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3487
+  /* "pywrapfst.pyx":3531
  * 
- * cpdef _MutableFst determinize(_Fst ifst,
- *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                               det_type=b"functional",
- *                               int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst determinize(Fst ifst,
+ *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *                              det_type=b"functional",
+ *                              int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__31 = fst::kShortestDelta;
+  __pyx_k__32 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3489
- *                               float delta=fst.kShortestDelta,
- *                               det_type=b"functional",
- *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                               int64 subsequential_label=0,
- *                               weight=None,
+  /* "pywrapfst.pyx":3533
+ *                              float delta=fst.kShortestDelta,
+ *                              det_type=b"functional",
+ *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                              int64 subsequential_label=0,
+ *                              weight=None,
  */
-  __pyx_k__32 = fst::kNoStateId;
+  __pyx_k__33 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3487
+  /* "pywrapfst.pyx":3531
  * 
- * cpdef _MutableFst determinize(_Fst ifst,
- *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                               det_type=b"functional",
- *                               int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst determinize(Fst ifst,
+ *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *                              det_type=b"functional",
+ *                              int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__31 = fst::kShortestDelta;
+  __pyx_k__32 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3489
- *                               float delta=fst.kShortestDelta,
- *                               det_type=b"functional",
- *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                               int64 subsequential_label=0,
- *                               weight=None,
+  /* "pywrapfst.pyx":3533
+ *                              float delta=fst.kShortestDelta,
+ *                              det_type=b"functional",
+ *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                              int64 subsequential_label=0,
+ *                              weight=None,
  */
-  __pyx_k__32 = fst::kNoStateId;
+  __pyx_k__33 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3583
+  /* "pywrapfst.pyx":3627
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,
- *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                                int64 nstate=fst.kNoStateId,
- *                                int64 subsequential_label=0,
+ * cpdef MutableFst disambiguate(Fst ifst,
+ *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                               int64 nstate=fst.kNoStateId,
+ *                               int64 subsequential_label=0,
  */
-  __pyx_k__33 = fst::kDelta;
+  __pyx_k__34 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3584
- * cpdef _MutableFst disambiguate(_Fst ifst,
- *                                float delta=fst.kDelta,
- *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                                int64 subsequential_label=0,
- *                                weight=None):
+  /* "pywrapfst.pyx":3628
+ * cpdef MutableFst disambiguate(Fst ifst,
+ *                               float delta=fst.kDelta,
+ *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                               int64 subsequential_label=0,
+ *                               weight=None):
  */
-  __pyx_k__34 = fst::kNoStateId;
+  __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3583
+  /* "pywrapfst.pyx":3627
  * 
- * cpdef _MutableFst disambiguate(_Fst ifst,
- *                                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                                int64 nstate=fst.kNoStateId,
- *                                int64 subsequential_label=0,
+ * cpdef MutableFst disambiguate(Fst ifst,
+ *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                               int64 nstate=fst.kNoStateId,
+ *                               int64 subsequential_label=0,
  */
-  __pyx_k__33 = fst::kDelta;
+  __pyx_k__34 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3584
- * cpdef _MutableFst disambiguate(_Fst ifst,
- *                                float delta=fst.kDelta,
- *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                                int64 subsequential_label=0,
- *                                weight=None):
+  /* "pywrapfst.pyx":3628
+ * cpdef MutableFst disambiguate(Fst ifst,
+ *                               float delta=fst.kDelta,
+ *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                               int64 subsequential_label=0,
+ *                               weight=None):
  */
-  __pyx_k__34 = fst::kNoStateId;
+  __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3653
+  /* "pywrapfst.pyx":3697
  * 
  * 
- * cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__35 = fst::kDelta;
-  __pyx_k__35 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3674
+  /* "pywrapfst.pyx":3718
  * 
  * 
- * cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:             # <<<<<<<<<<<<<<
+ * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__36 = fst::kDelta;
-  __pyx_k__36 = fst::kDelta;
+  __pyx_k__37 = fst::kDelta;
+  __pyx_k__37 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3730
+  /* "pywrapfst.pyx":3774
  * 
  * 
- * cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
+ * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__37 = fst::kDelta;
-  __pyx_k__37 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3755
+  /* "pywrapfst.pyx":3799
  * 
- * cpdef _MutableFst prune(_Fst ifst,
- *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                         int64 nstate=fst.kNoStateId,
- *                         weight=None):
+ * cpdef MutableFst prune(Fst ifst,
+ *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                        int64 nstate=fst.kNoStateId,
+ *                        weight=None):
  */
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3756
- * cpdef _MutableFst prune(_Fst ifst,
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                         weight=None):
+  /* "pywrapfst.pyx":3800
+ * cpdef MutableFst prune(Fst ifst,
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                        weight=None):
  *   """
  */
-  __pyx_k__39 = fst::kNoStateId;
+  __pyx_k__40 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3755
+  /* "pywrapfst.pyx":3799
  * 
- * cpdef _MutableFst prune(_Fst ifst,
- *                         float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                         int64 nstate=fst.kNoStateId,
- *                         weight=None):
+ * cpdef MutableFst prune(Fst ifst,
+ *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                        int64 nstate=fst.kNoStateId,
+ *                        weight=None):
  */
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3756
- * cpdef _MutableFst prune(_Fst ifst,
- *                         float delta=fst.kDelta,
- *                         int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                         weight=None):
+  /* "pywrapfst.pyx":3800
+ * cpdef MutableFst prune(Fst ifst,
+ *                        float delta=fst.kDelta,
+ *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                        weight=None):
  *   """
  */
-  __pyx_k__39 = fst::kNoStateId;
+  __pyx_k__40 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3786
+  /* "pywrapfst.pyx":3830
  * 
- * cpdef _MutableFst push(_Fst ifst,
- *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                        bool push_weights=False,
- *                        bool push_labels=False,
+ * cpdef MutableFst push(Fst ifst,
+ *                       float delta=fst.kDelta,             # <<<<<<<<<<<<<<
+ *                       bool push_weights=False,
+ *                       bool push_labels=False,
  */
-  __pyx_k__40 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3785
+  /* "pywrapfst.pyx":3829
  * 
  * 
- * cpdef _MutableFst push(_Fst ifst,             # <<<<<<<<<<<<<<
- *                        float delta=fst.kDelta,
- *                        bool push_weights=False,
+ * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
+ *                       float delta=fst.kDelta,
+ *                       bool push_weights=False,
  */
-  __pyx_k__40 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3845
- *                           _Fst ifst2,
+  /* "pywrapfst.pyx":3888
+ *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__41 = fst::kDelta;
+  __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3848
+  /* "pywrapfst.pyx":3891
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
  *   """
  *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__42 = INT32_MAX;
+  __pyx_k__43 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3845
- *                           _Fst ifst2,
+  /* "pywrapfst.pyx":3888
+ *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                           time_t seed=0,
  *                           select=b"uniform",
  */
-  __pyx_k__41 = fst::kDelta;
+  __pyx_k__42 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3848
+  /* "pywrapfst.pyx":3891
  *                           time_t seed=0,
  *                           select=b"uniform",
  *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
  *   """
  *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__42 = INT32_MAX;
+  __pyx_k__43 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3897
- *                           time_t seed=0,
- *                           select=b"uniform",
- *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
- *                           bool weighted=False,
- *                           bool remove_total_weight=False):
+  /* "pywrapfst.pyx":3940
+ *                          time_t seed=0,
+ *                          select=b"uniform",
+ *                          int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
+ *                          bool weighted=False,
+ *                          bool remove_total_weight=False):
  */
-  __pyx_k__43 = INT32_MAX;
+  __pyx_k__44 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3893
+  /* "pywrapfst.pyx":3936
  * 
  * 
- * cpdef _MutableFst randgen(_Fst ifst,             # <<<<<<<<<<<<<<
- *                           int32 npath=1,
- *                           time_t seed=0,
+ * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
+ *                          int32 npath=1,
+ *                          time_t seed=0,
  */
-  __pyx_k__43 = INT32_MAX;
+  __pyx_k__44 = INT32_MAX;
 
-  /* "pywrapfst.pyx":4033
+  /* "pywrapfst.pyx":4076
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+ * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
  *                                                 float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                                                 int64 nstate=fst.kNoStateId,
  *                                                 queue_type=b"auto",
  */
-  __pyx_k__44 = fst::kShortestDelta;
+  __pyx_k__45 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4034
- * cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+  /* "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 *:
  */
-  __pyx_k__45 = fst::kNoStateId;
+  __pyx_k__46 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4057
+  /* "pywrapfst.pyx":4100
  * 
- * def shortestdistance(_Fst ifst,
+ * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                      int64 nstate=fst.kNoStateId,
  *                      queue_type=b"auto",
  */
-  __pyx_k__46 = fst::kShortestDelta;
+  __pyx_k__47 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4058
- * def shortestdistance(_Fst ifst,
+  /* "pywrapfst.pyx":4101
+ * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                      queue_type=b"auto",
  *                      bool reverse=False):
  */
-  __pyx_k__47 = fst::kNoStateId;
+  __pyx_k__48 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4056
+  /* "pywrapfst.pyx":4099
  * 
  * 
- * def shortestdistance(_Fst ifst,             # <<<<<<<<<<<<<<
+ * 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, 4056, __pyx_L1_error)
+  __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, 4056, __pyx_L1_error)
+  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;
 
-  /* "pywrapfst.pyx":4094
+  /* "pywrapfst.pyx":4137
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,
- *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                                int32 nshortest=1,
- *                                int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst shortestpath(Fst ifst,
+ *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *                               int32 nshortest=1,
+ *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__48 = fst::kShortestDelta;
+  __pyx_k__49 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4096
- *                                float delta=fst.kShortestDelta,
- *                                int32 nshortest=1,
- *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                                queue_type=b"auto",
- *                                bool unique=False,
+  /* "pywrapfst.pyx":4139
+ *                               float delta=fst.kShortestDelta,
+ *                               int32 nshortest=1,
+ *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                               queue_type=b"auto",
+ *                               bool unique=False,
  */
-  __pyx_k__49 = fst::kNoStateId;
+  __pyx_k__50 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4094
+  /* "pywrapfst.pyx":4137
  * 
- * cpdef _MutableFst shortestpath(_Fst ifst,
- *                                float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                                int32 nshortest=1,
- *                                int64 nstate=fst.kNoStateId,
+ * cpdef MutableFst shortestpath(Fst ifst,
+ *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *                               int32 nshortest=1,
+ *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__48 = fst::kShortestDelta;
+  __pyx_k__49 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4096
- *                                float delta=fst.kShortestDelta,
- *                                int32 nshortest=1,
- *                                int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                                queue_type=b"auto",
- *                                bool unique=False,
+  /* "pywrapfst.pyx":4139
+ *                               float delta=fst.kShortestDelta,
+ *                               int32 nshortest=1,
+ *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                               queue_type=b"auto",
+ *                               bool unique=False,
  */
-  __pyx_k__49 = fst::kNoStateId;
+  __pyx_k__50 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4251
+  /* "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, 4251, __pyx_L1_error)
-  __pyx_k__50 = __pyx_t_5;
+  __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":4252
+  /* "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, 4252, __pyx_L1_error)
-  __pyx_k__51 = __pyx_t_5;
+  __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":4360
+  /* "pywrapfst.pyx":4403
  * 
  *   @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, 4360, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":4359
+  /* "pywrapfst.pyx":4402
  *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def open(cls, *sources):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4359, __pyx_L1_error)
+  __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, 4360, __pyx_L1_error)
+  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_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4511
+  /* "pywrapfst.pyx":4553
  * 
  *   @classmethod
  *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4511, __pyx_L1_error)
+  __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);
 
-  /* "pywrapfst.pyx":4510
+  /* "pywrapfst.pyx":4552
  *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def create(cls, source, arc_type=b"standard", far_type=b"default"):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __pyx_L1_error)
+  __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, 4511, __pyx_L1_error)
+  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_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4606
+  /* "pywrapfst.pyx":4644
  * 
  * # Masks fst_error_fatal in-module.
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -53137,8 +53546,8 @@ if (!__Pyx_RefNanny) {
 
   /* "vector.from_py":45
  * 
- * @cname("__pyx_convert_vector_from_py___pyx_t_10basictypes_int64")
- * cdef vector[X] __pyx_convert_vector_from_py___pyx_t_10basictypes_int64(object o) except *:             # <<<<<<<<<<<<<<
+ * @cname("__pyx_convert_vector_from_py_int64")
+ * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:             # <<<<<<<<<<<<<<
  *     cdef vector[X] v
  *     for item in o:
  */
@@ -54523,43 +54932,43 @@ static int __Pyx_setup_reduce(PyObject* type_obj) {
     PyObject *setstate = NULL;
     PyObject *setstate_cython = NULL;
 #if CYTHON_USE_PYTYPE_LOOKUP
-    if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto GOOD;
+    if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD;
 #else
-    if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto GOOD;
+    if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD;
 #endif
 #if CYTHON_USE_PYTYPE_LOOKUP
-    object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto BAD;
+    object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD;
 #else
-    object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto BAD;
+    object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD;
 #endif
-    reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto BAD;
+    reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD;
     if (reduce_ex == object_reduce_ex) {
 #if CYTHON_USE_PYTYPE_LOOKUP
-        object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto BAD;
+        object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD;
 #else
-        object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto BAD;
+        object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD;
 #endif
-        reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto BAD;
+        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 BAD;
-            ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto BAD;
-            ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto BAD;
+            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;
             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 BAD;
-                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto BAD;
-                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto BAD;
+                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;
             }
             PyType_Modified((PyTypeObject*)type_obj);
         }
     }
-    goto GOOD;
-BAD:
+    goto __PYX_GOOD;
+__PYX_BAD:
     if (!PyErr_Occurred())
         PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name);
     ret = -1;
-GOOD:
+__PYX_GOOD:
 #if !CYTHON_USE_PYTYPE_LOOKUP
     Py_XDECREF(object_reduce);
     Py_XDECREF(object_reduce_ex);
@@ -54809,644 +55218,6 @@ static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) {
     return result;
 }
 
-/* FetchCommonType */
-static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
-    PyObject* fake_module;
-    PyTypeObject* cached_type = NULL;
-    fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
-    if (!fake_module) return NULL;
-    Py_INCREF(fake_module);
-    cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
-    if (cached_type) {
-        if (!PyType_Check((PyObject*)cached_type)) {
-            PyErr_Format(PyExc_TypeError,
-                "Shared Cython type %.200s is not a type object",
-                type->tp_name);
-            goto bad;
-        }
-        if (cached_type->tp_basicsize != type->tp_basicsize) {
-            PyErr_Format(PyExc_TypeError,
-                "Shared Cython type %.200s has the wrong size, try recompiling",
-                type->tp_name);
-            goto bad;
-        }
-    } else {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
-        PyErr_Clear();
-        if (PyType_Ready(type) < 0) goto bad;
-        if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
-            goto bad;
-        Py_INCREF(type);
-        cached_type = type;
-    }
-done:
-    Py_DECREF(fake_module);
-    return cached_type;
-bad:
-    Py_XDECREF(cached_type);
-    cached_type = NULL;
-    goto done;
-}
-
-/* CythonFunction */
-#include <structmember.h>
-static PyObject *
-__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
-{
-    if (unlikely(op->func_doc == NULL)) {
-        if (op->func.m_ml->ml_doc) {
-#if PY_MAJOR_VERSION >= 3
-            op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
-#else
-            op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
-#endif
-            if (unlikely(op->func_doc == NULL))
-                return NULL;
-        } else {
-            Py_INCREF(Py_None);
-            return Py_None;
-        }
-    }
-    Py_INCREF(op->func_doc);
-    return op->func_doc;
-}
-static int
-__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
-{
-    PyObject *tmp = op->func_doc;
-    if (value == NULL) {
-        value = Py_None;
-    }
-    Py_INCREF(value);
-    op->func_doc = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    if (unlikely(op->func_name == NULL)) {
-#if PY_MAJOR_VERSION >= 3
-        op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
-#else
-        op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
-#endif
-        if (unlikely(op->func_name == NULL))
-            return NULL;
-    }
-    Py_INCREF(op->func_name);
-    return op->func_name;
-}
-static int
-__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
-{
-    PyObject *tmp;
-#if PY_MAJOR_VERSION >= 3
-    if (unlikely(value == NULL || !PyUnicode_Check(value)))
-#else
-    if (unlikely(value == NULL || !PyString_Check(value)))
-#endif
-    {
-        PyErr_SetString(PyExc_TypeError,
-                        "__name__ must be set to a string object");
-        return -1;
-    }
-    tmp = op->func_name;
-    Py_INCREF(value);
-    op->func_name = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    Py_INCREF(op->func_qualname);
-    return op->func_qualname;
-}
-static int
-__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
-{
-    PyObject *tmp;
-#if PY_MAJOR_VERSION >= 3
-    if (unlikely(value == NULL || !PyUnicode_Check(value)))
-#else
-    if (unlikely(value == NULL || !PyString_Check(value)))
-#endif
-    {
-        PyErr_SetString(PyExc_TypeError,
-                        "__qualname__ must be set to a string object");
-        return -1;
-    }
-    tmp = op->func_qualname;
-    Py_INCREF(value);
-    op->func_qualname = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
-{
-    PyObject *self;
-    self = m->func_closure;
-    if (self == NULL)
-        self = Py_None;
-    Py_INCREF(self);
-    return self;
-}
-static PyObject *
-__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    if (unlikely(op->func_dict == NULL)) {
-        op->func_dict = PyDict_New();
-        if (unlikely(op->func_dict == NULL))
-            return NULL;
-    }
-    Py_INCREF(op->func_dict);
-    return op->func_dict;
-}
-static int
-__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context)
-{
-    PyObject *tmp;
-    if (unlikely(value == NULL)) {
-        PyErr_SetString(PyExc_TypeError,
-               "function's dictionary may not be deleted");
-        return -1;
-    }
-    if (unlikely(!PyDict_Check(value))) {
-        PyErr_SetString(PyExc_TypeError,
-               "setting function's dictionary to a non-dict");
-        return -1;
-    }
-    tmp = op->func_dict;
-    Py_INCREF(value);
-    op->func_dict = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    Py_INCREF(op->func_globals);
-    return op->func_globals;
-}
-static PyObject *
-__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-static PyObject *
-__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context)
-{
-    PyObject* result = (op->func_code) ? op->func_code : Py_None;
-    Py_INCREF(result);
-    return result;
-}
-static int
-__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
-    int result = 0;
-    PyObject *res = op->defaults_getter((PyObject *) op);
-    if (unlikely(!res))
-        return -1;
-    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
-    Py_INCREF(op->defaults_tuple);
-    op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
-    Py_INCREF(op->defaults_kwdict);
-    #else
-    op->defaults_tuple = PySequence_ITEM(res, 0);
-    if (unlikely(!op->defaults_tuple)) result = -1;
-    else {
-        op->defaults_kwdict = PySequence_ITEM(res, 1);
-        if (unlikely(!op->defaults_kwdict)) result = -1;
-    }
-    #endif
-    Py_DECREF(res);
-    return result;
-}
-static int
-__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
-    if (!value) {
-        value = Py_None;
-    } else if (value != Py_None && !PyTuple_Check(value)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "__defaults__ must be set to a tuple object");
-        return -1;
-    }
-    Py_INCREF(value);
-    tmp = op->defaults_tuple;
-    op->defaults_tuple = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) {
-    PyObject* result = op->defaults_tuple;
-    if (unlikely(!result)) {
-        if (op->defaults_getter) {
-            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
-            result = op->defaults_tuple;
-        } else {
-            result = Py_None;
-        }
-    }
-    Py_INCREF(result);
-    return result;
-}
-static int
-__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
-    if (!value) {
-        value = Py_None;
-    } else if (value != Py_None && !PyDict_Check(value)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "__kwdefaults__ must be set to a dict object");
-        return -1;
-    }
-    Py_INCREF(value);
-    tmp = op->defaults_kwdict;
-    op->defaults_kwdict = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) {
-    PyObject* result = op->defaults_kwdict;
-    if (unlikely(!result)) {
-        if (op->defaults_getter) {
-            if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
-            result = op->defaults_kwdict;
-        } else {
-            result = Py_None;
-        }
-    }
-    Py_INCREF(result);
-    return result;
-}
-static int
-__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) {
-    PyObject* tmp;
-    if (!value || value == Py_None) {
-        value = NULL;
-    } else if (!PyDict_Check(value)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "__annotations__ must be set to a dict object");
-        return -1;
-    }
-    Py_XINCREF(value);
-    tmp = op->func_annotations;
-    op->func_annotations = value;
-    Py_XDECREF(tmp);
-    return 0;
-}
-static PyObject *
-__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) {
-    PyObject* result = op->func_annotations;
-    if (unlikely(!result)) {
-        result = PyDict_New();
-        if (unlikely(!result)) return NULL;
-        op->func_annotations = result;
-    }
-    Py_INCREF(result);
-    return result;
-}
-static PyGetSetDef __pyx_CyFunction_getsets[] = {
-    {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
-    {(char *) "__doc__",  (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
-    {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
-    {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
-    {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
-    {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
-    {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
-    {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
-    {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
-    {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
-    {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
-    {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
-    {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
-    {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
-    {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
-    {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
-    {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
-    {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
-    {0, 0, 0, 0, 0}
-};
-static PyMemberDef __pyx_CyFunction_members[] = {
-    {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), PY_WRITE_RESTRICTED, 0},
-    {0, 0, 0,  0, 0}
-};
-static PyObject *
-__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
-{
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(m->func.m_ml->ml_name);
-#else
-    return PyString_FromString(m->func.m_ml->ml_name);
-#endif
-}
-static PyMethodDef __pyx_CyFunction_methods[] = {
-    {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
-    {0, 0, 0, 0}
-};
-#if PY_VERSION_HEX < 0x030500A0
-#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
-#else
-#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
-#endif
-static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
-                                      PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
-    __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
-    if (op == NULL)
-        return NULL;
-    op->flags = flags;
-    __Pyx_CyFunction_weakreflist(op) = NULL;
-    op->func.m_ml = ml;
-    op->func.m_self = (PyObject *) op;
-    Py_XINCREF(closure);
-    op->func_closure = closure;
-    Py_XINCREF(module);
-    op->func.m_module = module;
-    op->func_dict = NULL;
-    op->func_name = NULL;
-    Py_INCREF(qualname);
-    op->func_qualname = qualname;
-    op->func_doc = NULL;
-    op->func_classobj = NULL;
-    op->func_globals = globals;
-    Py_INCREF(op->func_globals);
-    Py_XINCREF(code);
-    op->func_code = code;
-    op->defaults_pyobjects = 0;
-    op->defaults = NULL;
-    op->defaults_tuple = NULL;
-    op->defaults_kwdict = NULL;
-    op->defaults_getter = NULL;
-    op->func_annotations = NULL;
-    PyObject_GC_Track(op);
-    return (PyObject *) op;
-}
-static int
-__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
-{
-    Py_CLEAR(m->func_closure);
-    Py_CLEAR(m->func.m_module);
-    Py_CLEAR(m->func_dict);
-    Py_CLEAR(m->func_name);
-    Py_CLEAR(m->func_qualname);
-    Py_CLEAR(m->func_doc);
-    Py_CLEAR(m->func_globals);
-    Py_CLEAR(m->func_code);
-    Py_CLEAR(m->func_classobj);
-    Py_CLEAR(m->defaults_tuple);
-    Py_CLEAR(m->defaults_kwdict);
-    Py_CLEAR(m->func_annotations);
-    if (m->defaults) {
-        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
-        int i;
-        for (i = 0; i < m->defaults_pyobjects; i++)
-            Py_XDECREF(pydefaults[i]);
-        PyObject_Free(m->defaults);
-        m->defaults = NULL;
-    }
-    return 0;
-}
-static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m)
-{
-    if (__Pyx_CyFunction_weakreflist(m) != NULL)
-        PyObject_ClearWeakRefs((PyObject *) m);
-    __Pyx_CyFunction_clear(m);
-    PyObject_GC_Del(m);
-}
-static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
-{
-    PyObject_GC_UnTrack(m);
-    __Pyx__CyFunction_dealloc(m);
-}
-static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
-{
-    Py_VISIT(m->func_closure);
-    Py_VISIT(m->func.m_module);
-    Py_VISIT(m->func_dict);
-    Py_VISIT(m->func_name);
-    Py_VISIT(m->func_qualname);
-    Py_VISIT(m->func_doc);
-    Py_VISIT(m->func_globals);
-    Py_VISIT(m->func_code);
-    Py_VISIT(m->func_classobj);
-    Py_VISIT(m->defaults_tuple);
-    Py_VISIT(m->defaults_kwdict);
-    if (m->defaults) {
-        PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
-        int i;
-        for (i = 0; i < m->defaults_pyobjects; i++)
-            Py_VISIT(pydefaults[i]);
-    }
-    return 0;
-}
-static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
-{
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-    if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
-        Py_INCREF(func);
-        return func;
-    }
-    if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
-        if (type == NULL)
-            type = (PyObject *)(Py_TYPE(obj));
-        return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
-    }
-    if (obj == Py_None)
-        obj = NULL;
-    return __Pyx_PyMethod_New(func, obj, type);
-}
-static PyObject*
-__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
-{
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromFormat("<cyfunction %U at %p>",
-                                op->func_qualname, (void *)op);
-#else
-    return PyString_FromFormat("<cyfunction %s at %p>",
-                               PyString_AsString(op->func_qualname), (void *)op);
-#endif
-}
-static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) {
-    PyCFunctionObject* f = (PyCFunctionObject*)func;
-    PyCFunction meth = f->m_ml->ml_meth;
-    Py_ssize_t size;
-    switch (f->m_ml->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) {
-    case METH_VARARGS:
-        if (likely(kw == NULL || PyDict_Size(kw) == 0))
-            return (*meth)(self, arg);
-        break;
-    case METH_VARARGS | METH_KEYWORDS:
-        return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw);
-    case METH_NOARGS:
-        if (likely(kw == NULL || PyDict_Size(kw) == 0)) {
-            size = PyTuple_GET_SIZE(arg);
-            if (likely(size == 0))
-                return (*meth)(self, NULL);
-            PyErr_Format(PyExc_TypeError,
-                "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)",
-                f->m_ml->ml_name, size);
-            return NULL;
-        }
-        break;
-    case METH_O:
-        if (likely(kw == NULL || PyDict_Size(kw) == 0)) {
-            size = PyTuple_GET_SIZE(arg);
-            if (likely(size == 1)) {
-                PyObject *result, *arg0;
-                #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-                arg0 = PyTuple_GET_ITEM(arg, 0);
-                #else
-                arg0 = PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL;
-                #endif
-                result = (*meth)(self, arg0);
-                #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
-                Py_DECREF(arg0);
-                #endif
-                return result;
-            }
-            PyErr_Format(PyExc_TypeError,
-                "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)",
-                f->m_ml->ml_name, size);
-            return NULL;
-        }
-        break;
-    default:
-        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
-                        "__Pyx_CyFunction_Call. METH_OLDARGS is no "
-                        "longer supported!");
-        return NULL;
-    }
-    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
-                 f->m_ml->ml_name);
-    return NULL;
-}
-static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
-    return __Pyx_CyFunction_CallMethod(func, ((PyCFunctionObject*)func)->m_self, arg, kw);
-}
-static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) {
-    PyObject *result;
-    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func;
-    if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
-        Py_ssize_t argc;
-        PyObject *new_args;
-        PyObject *self;
-        argc = PyTuple_GET_SIZE(args);
-        new_args = PyTuple_GetSlice(args, 1, argc);
-        if (unlikely(!new_args))
-            return NULL;
-        self = PyTuple_GetItem(args, 0);
-        if (unlikely(!self)) {
-            Py_DECREF(new_args);
-            return NULL;
-        }
-        result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw);
-        Py_DECREF(new_args);
-    } else {
-        result = __Pyx_CyFunction_Call(func, args, kw);
-    }
-    return result;
-}
-static PyTypeObject __pyx_CyFunctionType_type = {
-    PyVarObject_HEAD_INIT(0, 0)
-    "cython_function_or_method",
-    sizeof(__pyx_CyFunctionObject),
-    0,
-    (destructor) __Pyx_CyFunction_dealloc,
-    0,
-    0,
-    0,
-#if PY_MAJOR_VERSION < 3
-    0,
-#else
-    0,
-#endif
-    (reprfunc) __Pyx_CyFunction_repr,
-    0,
-    0,
-    0,
-    0,
-    __Pyx_CyFunction_CallAsMethod,
-    0,
-    0,
-    0,
-    0,
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    0,
-    (traverseproc) __Pyx_CyFunction_traverse,
-    (inquiry) __Pyx_CyFunction_clear,
-    0,
-#if PY_VERSION_HEX < 0x030500A0
-    offsetof(__pyx_CyFunctionObject, func_weakreflist),
-#else
-    offsetof(PyCFunctionObject, m_weakreflist),
-#endif
-    0,
-    0,
-    __pyx_CyFunction_methods,
-    __pyx_CyFunction_members,
-    __pyx_CyFunction_getsets,
-    0,
-    0,
-    __Pyx_CyFunction_descr_get,
-    0,
-    offsetof(__pyx_CyFunctionObject, func_dict),
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-    0,
-#if PY_VERSION_HEX >= 0x030400a1
-    0,
-#endif
-#if PY_VERSION_HEX >= 0x030800b1
-    0,
-#endif
-};
-static int __pyx_CyFunction_init(void) {
-    __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
-    if (unlikely(__pyx_CyFunctionType == NULL)) {
-        return -1;
-    }
-    return 0;
-}
-static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-    m->defaults = PyObject_Malloc(size);
-    if (unlikely(!m->defaults))
-        return PyErr_NoMemory();
-    memset(m->defaults, 0, size);
-    m->defaults_pyobjects = pyobjects;
-    return m->defaults;
-}
-static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-    m->defaults_tuple = tuple;
-    Py_INCREF(tuple);
-}
-static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-    m->defaults_kwdict = dict;
-    Py_INCREF(dict);
-}
-static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
-    __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
-    m->func_annotations = dict;
-    Py_INCREF(dict);
-}
-
 /* CLineInTraceback */
 #ifndef CYTHON_CLINE_IN_TRACEBACK
 static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) {
@@ -57374,6 +57145,45 @@ raise_neg_overflow:
     return (int) -1;
 }
 
+/* FetchCommonType */
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+    PyObject* fake_module;
+    PyTypeObject* cached_type = NULL;
+    fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+    if (!fake_module) return NULL;
+    Py_INCREF(fake_module);
+    cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+    if (cached_type) {
+        if (!PyType_Check((PyObject*)cached_type)) {
+            PyErr_Format(PyExc_TypeError,
+                "Shared Cython type %.200s is not a type object",
+                type->tp_name);
+            goto bad;
+        }
+        if (cached_type->tp_basicsize != type->tp_basicsize) {
+            PyErr_Format(PyExc_TypeError,
+                "Shared Cython type %.200s has the wrong size, try recompiling",
+                type->tp_name);
+            goto bad;
+        }
+    } else {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+        PyErr_Clear();
+        if (PyType_Ready(type) < 0) goto bad;
+        if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+            goto bad;
+        Py_INCREF(type);
+        cached_type = type;
+    }
+done:
+    Py_DECREF(fake_module);
+    return cached_type;
+bad:
+    Py_XDECREF(cached_type);
+    cached_type = NULL;
+    goto done;
+}
+
 /* PyObjectGetMethod */
 static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) {
     PyObject *attr;
@@ -58406,6 +58216,9 @@ static PyTypeObject __pyx_GeneratorType_type = {
 #if PY_VERSION_HEX >= 0x030800b1
     0,
 #endif
+#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
+    0,
+#endif
 };
 static int __pyx_Generator_init(void) {
     __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
index 823d68d..d06775f 100644 (file)
@@ -87,13 +87,18 @@ cdef Weight _power(Weight lhs, size_t n)
 # SymbolTable.
 
 ctypedef fst.SymbolTable * SymbolTable_ptr
+ctypedef const fst.SymbolTable * const_SymbolTable_ptr
 
 
 cdef class _SymbolTable(object):
 
-  cdef fst.SymbolTable *_table
+  cdef const fst.SymbolTable *_raw(self)
 
-  cpdef int64 available_key(self)
+  cdef void _raise_nonexistent(self) except *
+
+  cdef const fst.SymbolTable *_raw_ptr_or_raise(self) except *
+
+  cpdef int64 available_key(self) except *
 
   cpdef bytes checksum(self)
 
@@ -103,11 +108,11 @@ cdef class _SymbolTable(object):
 
   cpdef bytes labeled_checksum(self)
 
-  cpdef bool member(self, key)
+  cpdef bool member(self, key) except *
 
-  cpdef string name(self)
+  cpdef string name(self) except *
 
-  cpdef size_t num_symbols(self)
+  cpdef size_t num_symbols(self) except *
 
   cpdef void write(self, source) except *
 
@@ -116,26 +121,39 @@ cdef class _SymbolTable(object):
   cpdef bytes write_to_string(self)
 
 
-cdef class _EncodeMapperSymbolTable(_SymbolTable):
+cdef class _EncodeMapperSymbolTableView(_SymbolTable):
+
+  # Indicates whether this view is of an input or output SymbolTable
+  cdef bool _input_side
 
   cdef shared_ptr[fst.EncodeMapperClass] _mapper
 
 
-cdef class _FstSymbolTable(_SymbolTable):
+cdef class _FstSymbolTableView(_SymbolTable):
+
+  # Indicates whether this view is of an input or output SymbolTable
+  cdef bool _input_side
 
   cdef shared_ptr[fst.FstClass] _fst
 
 
 cdef class _MutableSymbolTable(_SymbolTable):
 
-  cpdef int64 add_symbol(self, symbol, int64 key=?)
+  cdef fst.SymbolTable *_mutable_raw(self)
+
+  cdef fst.SymbolTable *_mutable_raw_ptr_or_raise(self) except *
+
+  cpdef int64 add_symbol(self, symbol, int64 key=?) except *
 
-  cpdef void add_table(self, _SymbolTable syms)
+  cpdef void add_table(self, _SymbolTable syms) except *
 
   cpdef void set_name(self, new_name) except *
 
 
-cdef class _MutableFstSymbolTable(_MutableSymbolTable):
+cdef class _MutableFstSymbolTableView(_MutableSymbolTable):
+
+  # Indicates whether this view is of an input or output SymbolTable
+  cdef bool _input_side
 
   cdef shared_ptr[fst.MutableFstClass] _mfst
 
@@ -145,43 +163,34 @@ cdef class SymbolTable(_MutableSymbolTable):
   cdef unique_ptr[fst.SymbolTable] _smart_table
 
 
-cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(
-    fst.SymbolTable *table,
-    shared_ptr[fst.EncodeMapperClass] encoder)
+cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(
+    shared_ptr[fst.EncodeMapperClass] encoder, bool input_side)
 
 
-cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
-                                          shared_ptr[fst.FstClass] ifst)
+cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,
+                                                  bool input_side)
 
 
-cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(
-    fst.SymbolTable *table,
-    shared_ptr[fst.MutableFstClass] ifst)
+cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(
+    shared_ptr[fst.MutableFstClass] ifst, bool input_side)
 
 
-cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table)
+cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table)
 
 
 cpdef _SymbolTable _read_SymbolTable_from_string(state)
 
 
-cdef class SymbolTableIterator(object):
+cdef class _SymbolTableIterator(object):
 
-  cdef shared_ptr[fst.SymbolTable] _table
+  cdef _SymbolTable _table
   cdef unique_ptr[fst.SymbolTableIterator] _siter
 
-  cpdef bool done(self)
-
-  cpdef void next(self)
-
-  cpdef void reset(self)
-
-  cpdef string symbol(self)
 
-  cpdef int64 value(self)
+# EncodeMapper.
 
 
-# EncodeMapper.
+ctypedef fst.EncodeMapperClass * EncodeMapperClass_ptr
 
 
 cdef class EncodeMapper(object):
@@ -200,19 +209,20 @@ cdef class EncodeMapper(object):
 
   cpdef bytes write_to_string(self)
 
-  cpdef _EncodeMapperSymbolTable input_symbols(self)
+  cpdef _EncodeMapperSymbolTableView input_symbols(self)
 
-  cpdef _EncodeMapperSymbolTable output_symbols(self)
+  cpdef _EncodeMapperSymbolTableView output_symbols(self)
 
-  cpdef void set_input_symbols(self, _SymbolTable syms) except *
+  cdef void _set_input_symbols(self, _SymbolTable syms) except *
 
-  cpdef void set_output_symbols(self, _SymbolTable syms) except *
+  cdef void _set_output_symbols(self, _SymbolTable syms) except *
 
 
-cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper)
+cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper)
 
 cpdef EncodeMapper _read_EncodeMapper_from_string(state)
 
+
 # Fst.
 
 
@@ -222,7 +232,7 @@ ctypedef fst.MutableFstClass * MutableFstClass_ptr
 ctypedef fst.VectorFstClass * VectorFstClass_ptr
 
 
-cdef class _Fst(object):
+cdef class Fst(object):
 
   cdef shared_ptr[fst.FstClass] _fst
 
@@ -238,7 +248,7 @@ cdef class _Fst(object):
 
   cpdef ArcIterator arcs(self, int64 state)
 
-  cpdef _Fst copy(self)
+  cpdef Fst copy(self)
 
   cpdef void draw(self,
                   source,
@@ -256,13 +266,13 @@ cdef class _Fst(object):
                   int32 fontsize=?,
                   int32 precision=?,
                   float_format=?,
-                  bool show_weight_one=?)
+                  bool show_weight_one=?) except *
 
   cpdef Weight final(self, int64 state)
 
   cpdef string fst_type(self)
 
-  cpdef _FstSymbolTable input_symbols(self)
+  cpdef _FstSymbolTableView input_symbols(self)
 
   cpdef size_t num_arcs(self, int64 state) except *
 
@@ -270,7 +280,15 @@ cdef class _Fst(object):
 
   cpdef size_t num_output_epsilons(self, int64 state) except *
 
-  cpdef _FstSymbolTable output_symbols(self)
+  cpdef _FstSymbolTableView output_symbols(self)
+
+  cpdef string print(self,
+                    _SymbolTable isymbols=?,
+                    _SymbolTable osymbols=?,
+                    _SymbolTable ssymbols=?,
+                    bool acceptor=?,
+                    bool show_weight_one=?,
+                    missing_sym=?) except *
 
   cpdef uint64 properties(self, uint64 mask, bool test)
 
@@ -284,7 +302,7 @@ cdef class _Fst(object):
                     _SymbolTable ssymbols=?,
                     bool acceptor=?,
                     bool show_weight_one=?,
-                    missing_sym=?)
+                    missing_sym=?) except *
 
   cpdef bool verify(self)
 
@@ -295,7 +313,7 @@ cdef class _Fst(object):
   cpdef bytes write_to_string(self)
 
 
-cdef class _MutableFst(_Fst):
+cdef class MutableFst(Fst):
 
   cdef shared_ptr[fst.MutableFstClass] _mfst
 
@@ -303,17 +321,17 @@ cdef class _MutableFst(_Fst):
 
   cdef void _add_arc(self, int64 state, Arc arc) except *
 
-  cpdef int64 add_state(self) except *
+  cpdef int64 add_state(self)
 
-  cpdef void add_states(self, size_t) except *
+  cpdef void add_states(self, size_t)
 
   cdef void _arcsort(self, sort_type=?) except *
 
-  cdef void _closure(self, bool closure_plus=?) except *
+  cdef void _closure(self, bool closure_plus=?)
 
-  cdef void _concat(self, _Fst fst2) except *
+  cdef void _concat(self, Fst fst2) except *
 
-  cdef void _connect(self) except *
+  cdef void _connect(self)
 
   cdef void _decode(self, EncodeMapper) except *
 
@@ -323,7 +341,7 @@ cdef class _MutableFst(_Fst):
 
   cdef void _encode(self, EncodeMapper) except *
 
-  cdef void _invert(self) except *
+  cdef void _invert(self)
 
   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *
 
@@ -338,7 +356,7 @@ cdef class _MutableFst(_Fst):
   cdef void _push(self,
                   float delta=?,
                   bool remove_total_weight=?,
-                  bool to_final=?) except *
+                  bool to_final=?)
 
   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
 
@@ -354,7 +372,7 @@ cdef class _MutableFst(_Fst):
 
   cdef void _reserve_arcs(self, int64 state, size_t n) except *
 
-  cdef void _reserve_states(self, int64 n) except *
+  cdef void _reserve_states(self, int64 n)
 
   cdef void _reweight(self, potentials, bool to_final=?) except *
 
@@ -375,23 +393,26 @@ cdef class _MutableFst(_Fst):
 
   cdef void _set_output_symbols(self, _SymbolTable syms) except *
 
-  cdef void _topsort(self) except *
+  cdef void _topsort(self)
 
 
-# Construction helpers.
+cdef class VectorFst(MutableFst):
+
+    pass
 
 
-cdef _Fst _init_Fst(FstClass_ptr tfst)
+# Construction helpers.
+
 
-cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst)
+cdef Fst _init_Fst(FstClass_ptr tfst)
 
-cdef _Fst _init_XFst(FstClass_ptr tfst)
+cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst)
 
-cdef _MutableFst _create_Fst(arc_type=?)
+cdef Fst _init_XFst(FstClass_ptr tfst)
 
-cpdef _Fst _read(source)
+cpdef Fst _read_Fst(source)
 
-cpdef _Fst _read_Fst_from_string(state)
+cpdef Fst _read_Fst_from_string(state)
 
 
 # Iterators.
@@ -470,111 +491,103 @@ cdef class StateIterator(object):
 # Constructive operations on Fst.
 
 
-cdef _Fst _map(_Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
+cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
 
-cpdef _Fst arcmap(_Fst ifst,
-                  float delta=?,
-                  map_type=?,
-                  double power=?,
-                  weight=?)
+cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
 
-cpdef _MutableFst compose(_Fst ifst1,
-                          _Fst ifst2,
-                          compose_filter=?,
-                          bool connect=?)
+cpdef MutableFst compose(Fst ifst1,
+                         Fst ifst2,
+                         compose_filter=?,
+                         bool connect=?)
 
-cpdef _Fst convert(_Fst ifst, fst_type=?)
+cpdef Fst convert(Fst ifst, fst_type=?)
 
-cpdef _MutableFst determinize(_Fst ifst,
+cpdef MutableFst determinize(Fst ifst,
+                             float delta=?,
+                             det_type=?,
+                             int64 nstate=?,
+                             int64 subsequential_label=?,
+                             weight=?,
+                             bool increment_subsequential_label=?)
+
+cpdef MutableFst difference(Fst ifst1,
+                            Fst ifst2,
+                            compose_filter=?,
+                            bool connect=?)
+
+cpdef MutableFst disambiguate(Fst ifst,
                               float delta=?,
-                              det_type=?,
                               int64 nstate=?,
                               int64 subsequential_label=?,
-                              weight=?,
-                              bool increment_subsequential_label=?)
-
-cpdef _MutableFst difference(_Fst ifst1,
-                             _Fst ifst2,
-                             compose_filter=?,
-                             bool connect=?)
-
-cpdef _MutableFst disambiguate(_Fst ifst,
-                               float delta=?,
-                               int64 nstate=?,
-                               int64 subsequential_label=?,
-                               weight=?)
+                              weight=?)
 
-cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=?)
+cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)
 
-cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=?)
+cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)
 
-cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=?) except *
+cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *
 
-cpdef _MutableFst intersect(_Fst ifst1,
-                            _Fst ifst2,
-                            compose_filter=?,
-                            bool connect=?)
-
-cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=?)
+cpdef MutableFst intersect(Fst ifst1,
+                           Fst ifst2,
+                           compose_filter=?,
+                           bool connect=?)
 
-cpdef _MutableFst prune(_Fst ifst,
-                        float delta=?,
-                        int64 nstate=?,
-                        weight=?)
+cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)
 
-cpdef _MutableFst push(_Fst ifst,
+cpdef MutableFst prune(Fst ifst,
                        float delta=?,
-                       bool push_weights=?,
-                       bool push_labels=?,
-                       bool remove_common_affix=?,
-                       bool remove_total_weight=?,
-                       bool to_final=?)
-
-cpdef bool randequivalent(_Fst ifst1,
-                          _Fst ifst2,
+                       int64 nstate=?,
+                       weight=?)
+
+cpdef MutableFst push(Fst ifst,
+                      float delta=?,
+                      bool push_weights=?,
+                      bool push_labels=?,
+                      bool remove_common_affix=?,
+                      bool remove_total_weight=?,
+                      bool to_final=?)
+
+cpdef bool randequivalent(Fst ifst1,
+                          Fst ifst2,
                           int32 npath=?,
                           float delta=?,
                           time_t seed=?,
                           select=?,
                           int32 max_length=?) except *
 
-cpdef _MutableFst randgen(_Fst ifst,
-                          int32 npath=?,
-                          time_t seed=?,
-                          select=?,
-                          int32 max_length=?,
-                          bool remove_total_weight=?,
-                          bool weighted=?)
-
-cdef fst.ReplaceLabelType _get_replace_label_type(
-    string rlt,
-    bool epsilon_on_replace) except *
+cpdef MutableFst randgen(Fst ifst,
+                         int32 npath=?,
+                         time_t seed=?,
+                         select=?,
+                         int32 max_length=?,
+                         bool remove_total_weight=?,
+                         bool weighted=?)
 
-cpdef _MutableFst replace(pairs,
-                          call_arc_labeling=?,
-                          return_arc_labeling=?,
-                          bool epsilon_on_replace=?,
-                          int64 return_label=?)
+cpdef MutableFst replace(pairs,
+                         call_arc_labeling=?,
+                         return_arc_labeling=?,
+                         bool epsilon_on_replace=?,
+                         int64 return_label=?)
 
-cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=?)
+cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)
 
-cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
                                                 float delta=?,
                                                 int64 nstate=?,
                                                 queue_type=?,
                                                 bool reverse=?) except *
 
-cpdef _MutableFst shortestpath(_Fst ifst,
-                               float delta=?,
-                               int32 nshortest=?,
-                               int64 nstate=?,
-                               queue_type=?,
-                               bool unique=?,
-                               weight=?)
+cpdef MutableFst shortestpath(Fst ifst,
+                              float delta=?,
+                              int32 nshortest=?,
+                              int64 nstate=?,
+                              queue_type=?,
+                              bool unique=?,
+                              weight=?)
 
-cpdef _Fst statemap(_Fst ifst, map_type)
+cpdef Fst statemap(Fst ifst, map_type)
 
-cpdef _MutableFst synchronize(_Fst ifst)
+cpdef MutableFst synchronize(Fst ifst)
 
 
 # Compiler.
@@ -594,7 +607,7 @@ cdef class Compiler(object):
   cdef bool _keep_state_numbering
   cdef bool _allow_negative_labels
 
-  cpdef _Fst compile(self)
+  cpdef Fst compile(self)
 
   cpdef void write(self, expression)
 
@@ -613,9 +626,9 @@ cdef class FarReader(object):
 
   cpdef string far_type(self)
 
-  cpdef bool find(self, key) except *
+  cpdef bool find(self, key)
 
-  cpdef _Fst get_fst(self)
+  cpdef Fst get_fst(self)
 
   cpdef string get_key(self)
 
@@ -634,7 +647,7 @@ cdef class FarWriter(object):
 
   cdef void close(self)
 
-  cpdef void add(self, key, _Fst ifst) except *
+  cpdef void add(self, key, Fst ifst) except *
 
   cpdef bool error(self)
 
index 814f35d..66bc34c 100644 (file)
@@ -32,11 +32,11 @@ normal `k` prefix.
 # * Custom exceptions
 # * General helpers
 # * Weight and helpers
-# * _SymbolTable, _EncodeMapperSymbolTable, _FstSymbolTable,
-#   _MutableFstSymbolTable, SymbolTable, and helpers
-# * SymbolTableIterator
+# * _SymbolTable, _EncodeMapperSymbolTableView, _FstSymbolTableView,
+#   _MutableFstSymbolTableView, SymbolTable, and helpers
+# * _SymbolTableIterator
 # * EncodeMapper
-# * _Fst, _MutableFst, Fst, and helpers
+# * Fst, MutableFst, and VectorFst
 # * FST properties
 # * Arc, ArcIterator, and MutableArcIterator
 # * StateIterator
@@ -68,12 +68,13 @@ from posix.unistd cimport getpid
 
 # C++ imports.
 from libcpp cimport bool
-from libcpp.cast cimport const_cast
 from libcpp.cast cimport static_cast
 from libcpp.memory cimport static_pointer_cast
 
 # Missing C++ imports.
 from ios cimport ofstream
+from memory cimport WrapUnique
+from utility cimport move
 
 # Cython operator workarounds.
 from cython.operator cimport address as addr       # &foo
@@ -81,10 +82,14 @@ from cython.operator cimport dereference as deref  # *foo
 from cython.operator cimport preincrement as inc   # ++foo
 
 # Python imports.
+import logging
 import numbers
 import subprocess
 
-import logging
+# TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
+import warnings
+
+warnings.simplefilter("always", DeprecationWarning)
 
 # Google-only...
 # This only works, and is only needed, inside of Colab.
@@ -327,7 +332,7 @@ cdef fst.ReplaceLabelType _get_replace_label_type(
 ## Weight and helpers.
 
 
-cdef class Weight(object):
+cdef class Weight:
 
   """
   Weight(weight_type, weight_string)
@@ -640,24 +645,24 @@ cdef Weight _NoWeight(weight_type):
   return result
 
 
-## _SymbolTable, _MutableSymbolTable, _EncodeMapperSymbolTable, _FstSymbolTable,
-##  _MutableFstSymbolTable, SymbolTable, and helpers.
+# _SymbolTable, _MutableSymbolTable, _EncodeMapperSymbolTableView,
+# _FstSymbolTableView, _MutableFstSymbolTableView, SymbolTable, and helpers.
 #
 # SymbolTable hierarchy:
 #
 # _SymbolTable: abstract base class; has-a SymbolTable*
-# _EncodeMapperSymbolTable(_SymbolTable): constant symbol table returned by
+# _EncodeMapperSymbolTableView(_SymbolTable): constant symbol table returned by
 #     EncodeMapper.input_symbols/output_symbols
-# _FstSymbolTable(_SymbolTable): constant symbol table returned by
-#     _Fst.input_symbols/output_symbols
+# _FstSymbolTableView(_SymbolTable): constant symbol table returned by
+#     Fst.input_symbols/output_symbols
 #
 # _MutableSymbolTable(_SymbolTable): abstract base class adding mutation methods
-# _MutableFstSymbolTable(_MutableSymbolTable): mutable symbol table returned by
-#     _MutableFst.mutable_input_symbols/mutable_output_symbols
+# _MutableFstSymbolTableView(_MutableSymbolTable): mutable symbol table
+#     returned by MutableFst.mutable_input_symbols/mutable_output_symbols
 # SymbolTable(_MutableSymbolTable): adds constructor
 
 
-cdef class _SymbolTable(object):
+cdef class _SymbolTable:
 
   """
   (No constructor.)
@@ -676,20 +681,39 @@ cdef class _SymbolTable(object):
         "Cannot construct {}".format(self.__class__.__name__))
 
   def __iter__(self):
-    return SymbolTableIterator(self)
+    return _SymbolTableIterator(self)
 
   # Registers the class for pickling.
 
   def __reduce__(self):
     return (_read_SymbolTable_from_string, (self.write_to_string(),))
 
-  cpdef int64 available_key(self):
+  # Returns a raw const pointer to SymbolTable.
+  # Must be overridden by child classes.
+  # 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):
+    return NULL
+
+  # 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
+  # fst.SymbolTable is required.
+  cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
+    cdef const_SymbolTable_ptr raw = self._raw()
+    if raw == NULL:
+      self._raise_nonexistent()
+    return raw
+
+  cpdef int64 available_key(self) except *:
     """
     available_key(self)
 
     Returns an integer indicating the next available key index in the table.
     """
-    return self._table.AvailableKey()
+    return self._raw_ptr_or_raise().AvailableKey()
 
   cpdef bytes checksum(self):
     """
@@ -697,7 +721,7 @@ cdef class _SymbolTable(object):
 
     Returns a bytestring indicating the label-independent MD5 checksum.
     """
-    return self._table.CheckSum()
+    return self._raw_ptr_or_raise().CheckSum()
 
   cpdef SymbolTable copy(self):
     """
@@ -705,7 +729,7 @@ cdef class _SymbolTable(object):
 
     Returns a mutable copy of the SymbolTable.
     """
-    return _init_SymbolTable(self._table.Copy())
+    return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
 
   def find(self, key):
     """
@@ -724,10 +748,11 @@ cdef class _SymbolTable(object):
           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()
     try:
-      return self._table.FindIndex(tostring(key))
+      return raw.FindIndex(tostring(key))
     except FstArgError:
-      return self._table.FindSymbol(key)
+      return raw.FindSymbol(key)
 
   cpdef int64 get_nth_key(self, ssize_t pos) except *:
     """
@@ -741,7 +766,7 @@ cdef class _SymbolTable(object):
     Returns:
       The integer index of the n-th key, or NO_LABEL if not found.
     """
-    return self._table.GetNthKey(pos)
+    return self._raw_ptr_or_raise().GetNthKey(pos)
 
   cpdef bytes labeled_checksum(self):
     """
@@ -749,9 +774,9 @@ cdef class _SymbolTable(object):
 
     Returns a bytestring indicating the label-dependent MD5 checksum.
     """
-    return self._table.LabeledCheckSum()
+    return self._raw_ptr_or_raise().LabeledCheckSum()
 
-  cpdef bool member(self, key):
+  cpdef bool member(self, key) except *:
     """
     member(self, key)
 
@@ -767,29 +792,30 @@ cdef class _SymbolTable(object):
     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()
     try:
-      return self._table.MemberSymbol(tostring(key))
+      return raw.MemberSymbol(tostring(key))
     except FstArgError:
-      return self._table.MemberIndex(key)
+      return raw.MemberIndex(key)
 
   def __contains__(self, key):
     return self.member(key)
 
-  cpdef string name(self):
+  cpdef string name(self) except *:
     """
     name(self)
 
     Returns the symbol table's name.
     """
-    return self._table.Name()
+    return self._raw_ptr_or_raise().Name()
 
-  cpdef size_t num_symbols(self):
+  cpdef size_t num_symbols(self) except *:
     """
     num_symbols(self)
 
     Returns the number of symbols in the symbol table.
     """
-    return self._table.NumSymbols()
+    return self._raw_ptr_or_raise().NumSymbols()
 
   cpdef void write(self, source) except *:
     """
@@ -805,7 +831,7 @@ cdef class _SymbolTable(object):
     Raises:
       FstIOError: Write failed.
     """
-    if not self._table.Write(tostring(source)):
+    if not self._raw_ptr_or_raise().Write(tostring(source)):
       raise FstIOError("Write failed: {!r}".format(source))
 
   cpdef void write_text(self, source) except *:
@@ -822,7 +848,7 @@ cdef class _SymbolTable(object):
     Raises:
       FstIOError: Write failed.
     """
-    if not self._table.WriteText(tostring(source)):
+    if not self._raw_ptr_or_raise().WriteText(tostring(source)):
       raise FstIOError("Write failed: {!r}".format(source))
 
   cpdef bytes write_to_string(self):
@@ -838,12 +864,12 @@ cdef class _SymbolTable(object):
       FstIOError: Write to string failed.
     """
     cdef stringstream sstrm
-    if not self._table.Write(sstrm):
+    if not self._raw_ptr_or_raise().Write(sstrm):
       raise FstIOError("Write to string failed")
     return sstrm.str()
 
 
-cdef class _EncodeMapperSymbolTable(_SymbolTable):
+cdef class _EncodeMapperSymbolTableView(_SymbolTable):
 
   """
   (No constructor.)
@@ -859,11 +885,15 @@ cdef class _EncodeMapperSymbolTable(_SymbolTable):
   # Doing so will allow undefined behavior.
 
   def __repr__(self):
-    return "<const EncodeMapper SymbolTable {!r} at 0x{:x}>".format(self.name(),
-                                                                    id(self))
+    return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
+      self.name(), id(self))
 
+  cdef const_SymbolTable_ptr _raw(self):
+    return (self._mapper.get().InputSymbols() if self._input_side
+            else self._mapper.get().OutputSymbols())
 
-cdef class _FstSymbolTable(_SymbolTable):
+
+cdef class _FstSymbolTableView(_SymbolTable):
 
   """
   (No constructor.)
@@ -878,8 +908,12 @@ cdef class _FstSymbolTable(_SymbolTable):
   # Doing so will allow undefined behavior.
 
   def __repr__(self):
-    return "<const Fst SymbolTable {!r} at 0x{:x}>".format(self.name(),
-                                                           id(self))
+    return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
+                                                               id(self))
+
+  cdef const_SymbolTable_ptr _raw(self):
+    return (self._fst.get().InputSymbols() if self._input_side
+            else self._fst.get().OutputSymbols())
 
 
 cdef class _MutableSymbolTable(_SymbolTable):
@@ -893,7 +927,25 @@ cdef class _MutableSymbolTable(_SymbolTable):
   constructor and implementations of all methods of the wrapped SymbolTable.
   """
 
-  cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol):
+  cdef const_SymbolTable_ptr _raw(self):
+    return self._mutable_raw()
+
+  # Returns a mutable raw pointer to SymbolTable.
+  # Must be overridden by child classes.
+  # 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):
+    return NULL
+
+  # 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 *:
+    cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
+    if mutable_raw == NULL:
+      self._raise_nonexistent()
+    return mutable_raw
+
+  cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:
     """
     add_symbol(self, symbol, key=NO_SYMBOL)
 
@@ -910,13 +962,14 @@ cdef class _MutableSymbolTable(_SymbolTable):
     Returns:
       The integer key of the new symbol.
     """
-    cdef string symbol_string = tostring(symbol)
+    cdef string _symbol = tostring(symbol)
+    cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
     if key != fst.kNoSymbol:
-      return self._table.AddSymbol(symbol_string, key)
+      return mutable_raw.AddSymbol(_symbol, key)
     else:
-      return self._table.AddSymbol(symbol_string)
+      return mutable_raw.AddSymbol(_symbol)
 
-  cpdef void add_table(self, _SymbolTable syms):
+  cpdef void add_table(self, _SymbolTable syms) except *:
     """
     add_table(self, syms)
 
@@ -928,13 +981,13 @@ cdef class _MutableSymbolTable(_SymbolTable):
     Args:
       syms: A SymbolTable to be merged with the current table.
     """
-    self._table.AddTable(deref(syms._table))
+    self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
 
   cpdef void set_name(self, new_name) except *:
-    self._table.SetName(tostring(new_name))
+    self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
 
 
-cdef class _MutableFstSymbolTable(_MutableSymbolTable):
+cdef class _MutableFstSymbolTableView(_MutableSymbolTable):
   """
   (No constructor.)
 
@@ -942,7 +995,11 @@ cdef class _MutableFstSymbolTable(_MutableSymbolTable):
   """
 
   def __repr__(self):
-    return "<Fst SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+    return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+
+  cdef SymbolTable_ptr _mutable_raw(self):
+    return (self._mfst.get().MutableInputSymbols() if self._input_side else
+            self._mfst.get().MutableOutputSymbols())
 
 
 cdef class SymbolTable(_MutableSymbolTable):
@@ -966,8 +1023,10 @@ cdef class SymbolTable(_MutableSymbolTable):
     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
 
   def __init__(self, name="<unspecified>"):
-    self._table = new fst.SymbolTable(tostring(name))
-    self._smart_table.reset(self._table)
+    self._smart_table.reset(new fst.SymbolTable(tostring(name)))
+
+  cdef SymbolTable_ptr _mutable_raw(self):
+    return self._smart_table.get()
 
   @classmethod
   def read(cls, source):
@@ -988,7 +1047,7 @@ cdef class SymbolTable(_MutableSymbolTable):
     syms.reset(fst.SymbolTable.Read(tostring(source)))
     if syms.get() == NULL:
       raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(syms.release())
+    return _init_SymbolTable(move(syms))
 
   @classmethod
   def read_text(cls, source, bool allow_negative_labels=False):
@@ -1013,7 +1072,7 @@ cdef class SymbolTable(_MutableSymbolTable):
     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
     if syms.get() == NULL:
       raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(syms.release())
+    return _init_SymbolTable(move(syms))
 
   @classmethod
   def read_fst(cls, source, bool input_table):
@@ -1040,38 +1099,40 @@ cdef class SymbolTable(_MutableSymbolTable):
     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
     if syms.get() == NULL:
       raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(syms.release())
+    return _init_SymbolTable(move(syms))
 
 
-cdef _EncodeMapperSymbolTable _init_EncodeMapperSymbolTable(
-    fst.SymbolTable *table, shared_ptr[fst.EncodeMapperClass] mapper):
-  cdef _EncodeMapperSymbolTable result = (
-      _EncodeMapperSymbolTable.__new__(_EncodeMapperSymbolTable))
-  result._table = table
-  result._mapper = mapper
+cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(
+    shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
+  cdef _EncodeMapperSymbolTableView result = (
+      _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
+  result._mapper = move(mapper)
+  result._input_side = input_side
   return result
 
 
-cdef _FstSymbolTable _init_FstSymbolTable(fst.SymbolTable *table,
-                                          shared_ptr[fst.FstClass] ifst):
-  cdef _FstSymbolTable result = _FstSymbolTable.__new__(_FstSymbolTable)
-  result._table = table
-  result._fst = ifst
+cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,
+                                                  bool input_side):
+  cdef _FstSymbolTableView result = (
+      _FstSymbolTableView.__new__(_FstSymbolTableView))
+  result._fst = move(ifst)
+  result._input_side = input_side
   return result
 
 
-cdef _MutableFstSymbolTable _init_MutableFstSymbolTable(fst.SymbolTable *table,
-    shared_ptr[fst.MutableFstClass] ifst):
-  cdef _MutableFstSymbolTable result = (
-      _MutableFstSymbolTable.__new__(_MutableFstSymbolTable))
-  result._table = table
-  result._mfst = ifst
+cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(
+                                    shared_ptr[fst.MutableFstClass] ifst,
+                                    bool input_side):
+  cdef _MutableFstSymbolTableView result = (
+      _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
+  result._mfst = move(ifst)
+  result._input_side = input_side
   return result
 
 
-cdef SymbolTable _init_SymbolTable(fst.SymbolTable *table):
+cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
-  result._table = table
+  result._smart_table = move(table)
   return result
 
 
@@ -1082,7 +1143,7 @@ cpdef SymbolTable _read_SymbolTable_from_string(state):
   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
   if syms.get() == NULL:
     raise FstIOError("Read failed")
-  return _init_SymbolTable(syms.release())
+  return _init_SymbolTable(move(syms))
 
 
 # Constructive SymbolTable operations.
@@ -1100,7 +1161,8 @@ cpdef SymbolTable compact_symbol_table(_SymbolTable syms):
   Returns:
     A new compacted SymbolTable.
   """
-  return _init_SymbolTable(fst.CompactSymbolTable(deref(syms._table)))
+  return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(
+                                          deref(syms._raw_ptr_or_raise()))))
 
 
 cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):
@@ -1125,26 +1187,29 @@ cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):
   Returns:
     A new merged SymbolTable.
   """
-  return _init_SymbolTable(fst.MergeSymbolTable(deref(lhs._table),
-                                                deref(rhs._table), NULL))
-
+  return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
+                                          deref(lhs._raw_ptr_or_raise()),
+                                          deref(rhs._raw_ptr_or_raise()),
+                                          NULL)))
 
-## SymbolTableIterator.
 
+## _SymbolTableIterator.
 
-cdef class SymbolTableIterator(object):
 
+cdef class _SymbolTableIterator:
   """
-  SymbolTableIterator(syms)
+  _SymbolTableIterator(syms)
 
   This class is used for iterating over a symbol table.
   """
 
   def __repr__(self):
-    return "<SymbolTableIterator at 0x{:x}>".format(id(self))
+    return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
 
   def __init__(self, _SymbolTable syms):
-    self._siter.reset(new fst.SymbolTableIterator(deref(syms._table)))
+    self._table = syms
+    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):
@@ -1152,69 +1217,18 @@ cdef class SymbolTableIterator(object):
 
   # Magic method used to get a Pythonic API out of the C++ API.
   def __next__(self):
-    if self.done():
+    if self._table._raw_ptr_or_raise().end() == deref(self._siter):
       raise StopIteration
-    cdef int64 value = self.value()
-    cdef string symbol = self.symbol()
-    self.next()
-    return (value, symbol)
-
-  cpdef bool done(self):
-    """
-    done(self)
-
-    Indicates whether the iterator is exhausted or not.
-
-    Returns:
-      True if the iterator is exhausted, False otherwise.
-    """
-    return self._siter.get().Done()
-
-  cpdef void next(self):
-    """
-    next(self)
-
-    Advances the iterator.
-    """
-    self._siter.get().Next()
-
-  cpdef void reset(self):
-    """
-    reset(self)
-
-    Resets the iterator to the initial position.
-    """
-    self._siter.get().Reset()
-
-  cpdef string symbol(self):
-    """
-    symbol(self)
-
-    Returns the current symbol string.
-
-    This method returns the current symbol string at this point in the table.
-
-    Returns:
-      A symbol string.
-    """
-    return self._siter.get().Symbol()
-
-  cpdef int64 value(self):
-    """
-    value(self)
-
-    Returns the current integer index of the symbol.
-
-    Returns:
-      An integer index.
-    """
-    return self._siter.get().Value()
+    cdef int64 label = self._siter.get().Pair().Label()
+    cdef string symbol = self._siter.get().Pair().Symbol()
+    inc(deref(self._siter))
+    return (label, symbol)
 
 
 ## EncodeMapper.
 
 
-cdef class EncodeMapper(object):
+cdef class EncodeMapper:
 
   """
   EncodeMapper(arc_type="standard", encode_labels=False, encode_weights=False)
@@ -1246,7 +1260,7 @@ cdef class EncodeMapper(object):
                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))
+                                                 fst.ENCODE))
     if not self._mapper:
       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
 
@@ -1388,54 +1402,74 @@ cdef class EncodeMapper(object):
         raise FstIOError("Write to string failed")
       return sstrm.str()
 
-  cpdef _EncodeMapperSymbolTable input_symbols(self):
+  cpdef _EncodeMapperSymbolTableView input_symbols(self):
     """
     input_symbols(self)
 
     Returns the mapper's input symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-        self._mapper.get().InputSymbols())
-    if syms == NULL:
+    if self._mapper.get().InputSymbols() == NULL:
       return
-    return _init_EncodeMapperSymbolTable(syms, self._mapper)
+    return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
 
-  cpdef _EncodeMapperSymbolTable output_symbols(self):
+  cpdef _EncodeMapperSymbolTableView output_symbols(self):
     """
     output_symbols(self)
 
     Returns the mapper's output symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-        self._mapper.get().OutputSymbols())
-    if syms == NULL:
+    if self._mapper.get().OutputSymbols() == NULL:
+      return
+    return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
+
+  cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+    if syms is None:
+      self._mapper.get().SetInputSymbols(NULL)
       return
-    return _init_EncodeMapperSymbolTable(syms, self._mapper)
+    self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
 
-  cpdef void set_input_symbols(self, _SymbolTable syms) except *:
+  def set_input_symbols(self, _SymbolTable syms):
     """
     set_input_symbols(self, syms)
 
     Sets the mapper's input symbol table.
 
+    Passing None as a value will delete the input symbol table.
+
     Args:
       syms: A SymbolTable.
+
+    Returns:
+      self.
     """
-    self._mapper.get().SetInputSymbols(syms._table)
+    self._set_input_symbols(syms)
+    return self
+
+  cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+    if syms is None:
+      self._mapper.get().SetOutputSymbols(NULL)
+      return
+    self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
 
-  cpdef void set_output_symbols(self, _SymbolTable syms) except *:
+  def set_output_symbols(self, _SymbolTable syms):
     """
     set_output_symbols(self, syms)
 
     Sets the mapper's output symbol table.
 
+    Passing None as a value will delete the output symbol table.
+
     Args:
       syms: A SymbolTable.
+
+    Returns:
+      self.
     """
-    self._mapper.get().SetOutputSymbols(syms._table)
+    self._set_output_symbols(syms)
+    return self
 
 
-cdef EncodeMapper _init_EncodeMapper(fst.EncodeMapperClass *mapper):
+cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
   result._mapper.reset(mapper)
   return result
@@ -1451,16 +1485,16 @@ cpdef EncodeMapper _read_EncodeMapper_from_string(state):
   return _init_EncodeMapper(mapper.release())
 
 
-## _Fst, _MutableFst, Fst, and helpers.
+## Fst and MutableFst.
 #
 # Fst hierarchy:
 #
-# _Fst: base class; has-a FstClass*.
-# _MutableFst(_Fst): adds mutable methods.
-# Fst(source): pseudo-constructor.
+# Fst: base class; has-a FstClass*.
+# MutableFst(Fst): adds mutable methods.
+# VectorFst(MutableFst): add constructor.
 
 
-cdef class _Fst(object):
+cdef class Fst:
 
   """
   (No constructor.)
@@ -1510,13 +1544,13 @@ cdef class _Fst(object):
              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)
 
@@ -1534,7 +1568,7 @@ cdef class _Fst(object):
     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
 
   def __str__(self):
-    return self.text()
+    return self.print()
 
   cpdef string arc_type(self):
     """
@@ -1558,7 +1592,7 @@ cdef class _Fst(object):
     """
     return ArcIterator(self, state)
 
-  cpdef _Fst copy(self):
+  cpdef Fst copy(self):
     """
     copy(self)
 
@@ -1582,7 +1616,7 @@ cdef class _Fst(object):
                   int32 fontsize=14,
                   int32 precision=5,
                   float_format=b"g",
-                  bool show_weight_one=False):
+                  bool show_weight_one=False) except *:
     """
     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
          acceptor=False, title="", width=8.5, height=11, portrait=False,
@@ -1619,13 +1653,13 @@ cdef class _Fst(object):
     fstrm.reset(new ofstream(source_string))
     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
     if isymbols is not None:
-       _isymbols = isymbols._table
+       _isymbols = isymbols._raw_ptr_or_raise()
     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
     if osymbols is not None:
-       _osymbols = osymbols._table
-    cdef fst.SymbolTable *_ssymbols = NULL
+       _osymbols = osymbols._raw_ptr_or_raise()
+    cdef const fst.SymbolTable *_ssymbols = NULL
     if ssymbols is not None:
-      _ssymbols = ssymbols._table
+      _ssymbols = ssymbols._raw_ptr_or_raise()
     fst.Draw(deref(self._fst),
         _isymbols,
         _osymbols,
@@ -1674,17 +1708,16 @@ cdef class _Fst(object):
     """
     return self._fst.get().FstType()
 
-  cpdef _FstSymbolTable input_symbols(self):
+  cpdef _FstSymbolTableView input_symbols(self):
     """
     input_symbols(self)
 
     Returns the FST's input symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-      self._fst.get().InputSymbols())
+    cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
     if syms == NULL:
       return
-    return _init_FstSymbolTable(syms, self._fst)
+    return _init_FstSymbolTableView(self._fst, input_side=True)
 
   cpdef size_t num_arcs(self, int64 state) except *:
     """
@@ -1746,17 +1779,63 @@ cdef class _Fst(object):
       raise FstIndexError("State index out of range")
     return result
 
-  cpdef _FstSymbolTable output_symbols(self):
+  cpdef _FstSymbolTableView output_symbols(self):
     """
     output_symbols(self)
 
     Returns the FST's output symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = const_cast[SymbolTable_ptr](
-      self._fst.get().OutputSymbols())
+    cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
     if syms == NULL:
       return
-    return _init_FstSymbolTable(syms, self._fst)
+    return _init_FstSymbolTableView(self._fst, input_side=False)
+
+  cpdef string print(self, _SymbolTable isymbols=None,
+      _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+      bool acceptor=False, bool show_weight_one=False,
+      missing_sym=b"") except *:
+    """
+    print(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.
+    """
+    # Prints FST to stringstream, then returns resulting string.
+    cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
+    if isymbols is not None:
+       _isymbols = isymbols._raw_ptr_or_raise()
+    cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
+    if osymbols is not None:
+       _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
+    fst.Print(deref(self._fst),
+              sstrm,
+              b"<pywrapfst>",
+              _isymbols,
+              _osymbols,
+              _ssymbols,
+              acceptor,
+              show_weight_one,
+              tostring(missing_sym))
+    return sstrm.str()
 
   cpdef uint64 properties(self, uint64 mask, bool test):
     """
@@ -1778,6 +1857,42 @@ cdef class _Fst(object):
     """
     return self._fst.get().Properties(mask, test)
 
+  @classmethod
+  def read(cls, source):
+    """
+    read(source)
+
+    Reads an FST from a file.
+
+    Args:
+      source: The string location of the input file.
+
+    Returns:
+      An FST object.
+
+    Raises:
+      FstIOError: Read failed.
+    """
+    return _read_Fst(source)
+
+  @classmethod
+  def read_from_string(cls, state):
+    """
+    read_from_string(state)
+
+    Reads an FST from a serialized string.
+
+    Args:
+      state: A string containing the serialized FST.
+
+    Returns:
+      An FST object.
+
+    Raises:
+      FstIOError: Read failed.
+    """
+    return _read_Fst_from_string(state)
+
   cpdef int64 start(self):
     """
     start(self)
@@ -1797,12 +1912,17 @@ cdef class _Fst(object):
     """
     return StateIterator(self)
 
-  cpdef string text(self, _SymbolTable isymbols=None,
-      _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
-      bool acceptor=False, bool show_weight_one=False, missing_sym=b""):
+  # 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="")
+          show_weight_one=False, missing_sym="")
 
     Produces a human-readable string representation of the FST.
 
@@ -1821,29 +1941,14 @@ cdef class _Fst(object):
     Returns:
       A formatted string representing the machine.
     """
-    # Prints FST to stringstream, then returns resulting string.
-    cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
-    if isymbols is not None:
-       _isymbols = isymbols._table
-    cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
-    if osymbols is not None:
-       _osymbols = osymbols._table
-    cdef fst.SymbolTable *_ssymbols = NULL
-    if ssymbols is not None:
-      _ssymbols = ssymbols._table
-    if ssymbols is not None:
-      _ssymbols = ssymbols._table
-    cdef stringstream sstrm
-    fst.Print(deref(self._fst),
-              sstrm,
-              b"<pywrapfst>",
-              _isymbols,
-              _osymbols,
-              _ssymbols,
-              acceptor,
-              show_weight_one,
-              tostring(missing_sym))
-    return sstrm.str()
+    warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)
+    return self.print(isymbols,
+                      osymbols,
+                      ssymbols,
+                      acceptor,
+                      show_weight_one,
+                      missing_sym)
+
 
   cpdef bool verify(self):
     """
@@ -1902,14 +2007,14 @@ cdef class _Fst(object):
     return sstrm.str()
 
 
-cdef class _MutableFst(_Fst):
+cdef class MutableFst(Fst):
 
   """
   (No constructor.)
 
   Mutable FST class, wrapping MutableFstClass.
 
-  This class extends _Fst by adding mutation operations.
+  This class extends Fst by adding mutation operations.
   """
 
   cdef void _check_mutating_imethod(self) except *:
@@ -1919,13 +2024,11 @@ cdef class _MutableFst(_Fst):
     """
     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):
       raise FstIndexError("State index out of range")
     if not self._mfst.get().AddArc(state, deref(arc._arc)):
       raise FstOpError("Incompatible or invalid weight type")
-    self._check_mutating_imethod()
 
   def add_arc(self, int64 state, Arc arc):
     """
@@ -1947,7 +2050,7 @@ cdef class _MutableFst(_Fst):
     self._add_arc(state, arc)
     return self
 
-  cpdef int64 add_state(self) except *:
+  cpdef int64 add_state(self):
     """
     add_state(self)
 
@@ -1956,11 +2059,9 @@ cdef class _MutableFst(_Fst):
     Returns:
       The integer index of the new state.
     """
-    cdef int64 result = self._mfst.get().AddState()
-    self._check_mutating_imethod()
-    return result
+    return self._mfst.get().AddState()
 
-  cpdef void add_states(self, size_t n) except *:
+  cpdef void add_states(self, size_t n):
     """
     add_states(self, n)
 
@@ -1970,14 +2071,12 @@ cdef class _MutableFst(_Fst):
       n: The number of states to add.
     """
     self._mfst.get().AddStates(n)
-    self._check_mutating_imethod()
 
   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)
-    self._check_mutating_imethod()
 
   def arcsort(self, sort_type=b"ilabel"):
     """
@@ -2001,9 +2100,8 @@ cdef class _MutableFst(_Fst):
     self._arcsort(sort_type)
     return self
 
-  cdef void _closure(self, bool closure_plus=False) except *:
+  cdef void _closure(self, bool closure_plus=False):
     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
-    self._check_mutating_imethod()
 
   def closure(self, bool closure_plus=False):
     """
@@ -2026,11 +2124,11 @@ cdef class _MutableFst(_Fst):
     self._closure(closure_plus)
     return self
 
-  cdef void _concat(self, _Fst fst2) except *:
+  cdef void _concat(self, Fst fst2) except *:
     fst.Concat(self._mfst.get(), deref(fst2._fst))
     self._check_mutating_imethod()
 
-  def concat(self, _Fst fst2):
+  def concat(self, Fst fst2):
     """
     concat(self, fst2)
 
@@ -2050,9 +2148,8 @@ cdef class _MutableFst(_Fst):
     self._concat(fst2)
     return self
 
-  cdef void _connect(self) except *:
+  cdef void _connect(self):
     fst.Connect(self._mfst.get())
-    self._check_mutating_imethod()
 
   def connect(self):
     """
@@ -2171,9 +2268,8 @@ cdef class _MutableFst(_Fst):
     self._encode(mapper)
     return self
 
-  cdef void _invert(self) except *:
+  cdef void _invert(self):
     fst.Invert(self._mfst.get())
-    self._check_mutating_imethod()
 
   def invert(self):
     """
@@ -2190,7 +2286,8 @@ cdef class _MutableFst(_Fst):
     self._invert()
     return self
 
-  cdef void _minimize(self, float delta=fst.kShortestDelta,
+  cdef void _minimize(self,
+                      float delta=fst.kShortestDelta,
                       bool allow_nondet=False) except *:
     # This runs in-place when the second argument is null.
     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
@@ -2248,7 +2345,7 @@ cdef class _MutableFst(_Fst):
     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
     if syms == NULL:
       return
-    return _init_MutableFstSymbolTable(syms, self._mfst)
+    return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
 
   def mutable_output_symbols(self):
     """
@@ -2256,10 +2353,10 @@ cdef class _MutableFst(_Fst):
 
     Returns the FST's (mutable) output symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = self._mfst.get().MutableOutputSymbols()
+    cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
     if syms == NULL:
       return
-    return _init_MutableFstSymbolTable(syms, self._mfst)
+    return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
 
   cpdef int64 num_states(self):
     """
@@ -2271,7 +2368,6 @@ cdef class _MutableFst(_Fst):
 
   cdef void _project(self, bool project_output=False) except *:
     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
-    self._check_mutating_imethod()
 
   def project(self, bool project_output=False):
     """
@@ -2292,7 +2388,9 @@ cdef class _MutableFst(_Fst):
     self._project(project_output)
     return self
 
-  cdef void _prune(self, float delta=fst.kDelta, int64 nstate=fst.kNoStateId,
+  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.
     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
@@ -2329,10 +2427,9 @@ cdef class _MutableFst(_Fst):
   cdef void _push(self,
                   float delta=fst.kShortestDelta,
                   bool remove_total_weight=False,
-                  bool to_final=False) except *:
+                  bool to_final=False):
     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
              remove_total_weight)
-    self._check_mutating_imethod()
 
   def push(self,
            float delta=fst.kShortestDelta,
@@ -2418,16 +2515,16 @@ cdef class _MutableFst(_Fst):
       raise FstArgError("No new SymbolTables specified")
     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
     if old_isymbols is not None:
-      _old_isymbols = old_isymbols._table
+      _old_isymbols = old_isymbols._raw_ptr_or_raise()
     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
     if old_osymbols is not None:
-       _old_osymbols = old_osymbols._table
+       _old_osymbols = old_osymbols._raw_ptr_or_raise()
     cdef const fst.SymbolTable *_new_isymbols = NULL
     if new_isymbols is not None:
-      _new_isymbols = new_isymbols._table
+      _new_isymbols = new_isymbols._raw_ptr_or_raise()
     cdef const fst.SymbolTable *_new_osymbols = NULL
     if new_osymbols is not None:
-      _new_osymbols = new_osymbols._table
+      _new_osymbols = new_osymbols._raw_ptr_or_raise()
     fst.Relabel(self._mfst.get(),
         _old_isymbols,
         _new_isymbols,
@@ -2515,9 +2612,8 @@ cdef class _MutableFst(_Fst):
     self._reserve_arcs(state, n)
     return self
 
-  cdef void _reserve_states(self, int64 n) except *:
+  cdef void _reserve_states(self, int64 n):
     self._mfst.get().ReserveStates(n)
-    self._check_mutating_imethod()
 
   def reserve_states(self, int64 n):
     """
@@ -2651,8 +2747,7 @@ cdef class _MutableFst(_Fst):
     if syms is None:
       self._mfst.get().SetInputSymbols(NULL)
       return
-    self._mfst.get().SetInputSymbols(syms._table)
-    self._check_mutating_imethod()
+    self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
 
   def set_input_symbols(self, _SymbolTable syms):
     """
@@ -2675,8 +2770,7 @@ cdef class _MutableFst(_Fst):
     if syms is None:
       self._mfst.get().SetOutputSymbols(NULL)
       return
-    self._mfst.get().SetOutputSymbols(syms._table)
-    self._check_mutating_imethod()
+    self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
 
   def set_output_symbols(self, _SymbolTable syms):
     """
@@ -2718,7 +2812,6 @@ cdef class _MutableFst(_Fst):
   cdef void _set_start(self, int64 state) except *:
     if not self._mfst.get().SetStart(state):
       raise FstIndexError("State index out of range")
-    self._check_mutating_imethod()
 
   def set_start(self, int64 state):
     """
@@ -2738,11 +2831,10 @@ cdef class _MutableFst(_Fst):
     self._set_start(state)
     return self
 
-  cdef void _topsort(self) except *:
+  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()):
       logging.warning("Cannot topsort cyclic FST")
-    self._check_mutating_imethod()
 
   def topsort(self):
     """
@@ -2777,7 +2869,7 @@ cdef class _MutableFst(_Fst):
       self.
     """
     cdef vector[const_FstClass_ptr] _fsts2
-    cdef _Fst fst2
+    cdef Fst fst2
     for fst2 in fsts2:
       _fsts2.push_back(fst2._fst.get())
     fst.Union(self._mfst.get(), _fsts2)
@@ -2785,62 +2877,71 @@ cdef class _MutableFst(_Fst):
     return self
 
 
-# Pseudo-constructors for _Fst and _MutableFst.
+cdef class VectorFst(MutableFst):
+  """
+  VectorFst(arc_type="standard")
+
+  Constructs a concrete, empty, mutable FST.
+
+  Args:
+    arc_type: A string indicating the arc type.
+
+  Raises:
+    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())
+    self._mfst = static_pointer_cast[fst.MutableFstClass,
+                                     fst.FstClass](self._fst)
+
+
+# Pseudo-constructors for Fst and MutableFst.
 #
-# _init_Fst and _init_MutableFst use an FstClass pointer to instantiate _Fst
-# and _MutableFst objects, respectively. The latter function is only safe to
+# _init_Fst and _init_MutableFst use an FstClass pointer to instantiate Fst
+# and MutableFst objects, respectively. The latter function is only safe to
 # call when the FST being wrapped is known to be kMutable. The caller can
 # safely use it when they have either checked this bit (e.g., by using
 # _init_XFst) or have themselves constructed a mutable container for the
 # FstClass pointer they're passing (e.g., most of the constructive operations,
 # storing their results in a VectorFstClass, a derivative of MutableFstClass).
 #
-# _create_Fst constructs an empty VectorFstClass of a user-specified arc type,
-# and passes this pointer to _init_MutableFst.
-#
 # _read_Fst reads an FST from disk, performing FST conversion if requested, and
 # then passes this pointer to _init_XFst.
 #
-# The Python class Fst provides a wrapper for these two operations. The former
-# can be accessed by calling Fst(...), which acts like a class method, and the
-# latter via Fst.read(...), which acts like a static method. This is a bit
-# nasty, but totally hidden from the Python user.
+# _read_Fst_from_string reads an FST serialization directly from a string.
 
 
-cdef _Fst _init_Fst(FstClass_ptr tfst):
+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)
   ofst._fst.reset(tfst)
   return ofst
 
 
-cdef _MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
+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)
   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
 
 
-cdef _Fst _init_XFst(FstClass_ptr tfst):
+cdef Fst _init_XFst(FstClass_ptr tfst):
   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
   else:
     return _init_Fst(tfst)
 
 
-cdef _MutableFst _create_Fst(arc_type=b"standard"):
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
-  if tfst.get() == NULL:
-    raise FstOpError("Unknown arc type: {!r}".format(arc_type))
-  return _init_MutableFst(tfst.release())
-
-
-cpdef _Fst _read(source):
+cpdef Fst _read_Fst(source):
   cdef unique_ptr[fst.FstClass] tfst
   tfst.reset(fst.FstClass.Read(tostring(source)))
   if tfst.get() == NULL:
@@ -2848,7 +2949,7 @@ cpdef _Fst _read(source):
   return _init_XFst(tfst.release())
 
 
-cpdef _Fst _read_Fst_from_string(state):
+cpdef Fst _read_Fst_from_string(state):
   cdef stringstream sstrm
   sstrm << tostring(state)
   cdef unique_ptr[fst.FstClass] tfst
@@ -2858,63 +2959,6 @@ cpdef _Fst _read_Fst_from_string(state):
   return _init_XFst(tfst.release())
 
 
-class Fst(object):
-
-   """
-   Fst(arc_type="standard")
-
-   Constructs an empty FST.
-
-   Args:
-     arc_type: A string indicating the arc type.
-
-   Raises:
-     FstError: Unknown arc type.
-
-   Raises:
-     FstOpError: operation failed.
-   """
-
-   def __new__(cls, arc_type=b"standard"):
-    return _create_Fst(arc_type)
-
-   @staticmethod
-   def read(source):
-     """
-     read(source)
-
-     Reads an FST from a file.
-
-     Args:
-       source: The string location of the input file.
-
-     Returns:
-       An FST object.
-
-     Raises:
-       FstIOError: Read failed.
-     """
-     return _read(source)
-
-   @staticmethod
-   def read_from_string(state):
-     """
-     read_from_string(state)
-
-     Reads an FST from a serialized string.
-
-     Args:
-       state: A string containing the serialized FST.
-
-     Returns:
-       An FST object.
-
-     Raises:
-       FstIOError: Read failed.
-     """
-     return _read_Fst_from_string(state)
-
-
 ## FST constants.
 
 
@@ -3009,7 +3053,7 @@ ENCODE_FLAGS = fst.kEncodeFlags
 ## Arc, ArcIterator, and MutableArcIterator.
 
 
-cdef class Arc(object):
+cdef class Arc:
 
   """
   Arc(ilabel, olabel, weight, nextstate)
@@ -3076,7 +3120,7 @@ cdef Arc _init_Arc(const fst.ArcClass &arc):
   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)
 
 
-cdef class ArcIterator(object):
+cdef class ArcIterator:
 
   """
   ArcIterator(ifst, state)
@@ -3087,7 +3131,7 @@ cdef class ArcIterator(object):
   def __repr__(self):
     return "<ArcIterator at 0x{:x}>".format(id(self))
 
-  def __init__(self, _Fst ifst, int64 state):
+  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.
@@ -3187,7 +3231,7 @@ cdef class ArcIterator(object):
     return _init_Arc(self._aiter.get().Value())
 
 
-cdef class MutableArcIterator(object):
+cdef class MutableArcIterator:
 
   """
   MutableArcIterator(ifst, state)
@@ -3199,14 +3243,14 @@ cdef class MutableArcIterator(object):
   def __repr__(self):
     return "<MutableArcIterator at 0x{:x}>".format(id(self))
 
-  def __init__(self, _MutableFst ifst, int64 state):
+  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
     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))
 
-  # Magic method used to get a Pythonic Iterator API out of the C++ API
+  # Magic method used to get a Pythonic Iterator API out of the C++ API.
   def __iter__(self):
     while not self.done():
       yield self.value()
@@ -3307,7 +3351,7 @@ cdef class MutableArcIterator(object):
 ## StateIterator.
 
 
-cdef class StateIterator(object):
+cdef class StateIterator:
 
   """
   StateIterator(ifst)
@@ -3318,7 +3362,7 @@ cdef class StateIterator(object):
   def __repr__(self):
     return "<StateIterator at 0x{:x}>".format(id(self))
 
-  def __init__(self, _Fst ifst):
+  def __init__(self, Fst ifst):
     # 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)))
@@ -3374,7 +3418,7 @@ cdef class StateIterator(object):
 ## FST operations.
 
 
-cdef _Fst _map(_Fst ifst,
+cdef Fst _map(Fst ifst,
                float delta=fst.kDelta,
                map_type=b"identity",
                double power=1.,
@@ -3390,11 +3434,11 @@ cdef _Fst _map(_Fst ifst,
   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
 
 
-cpdef _Fst arcmap(_Fst ifst,
-                  float delta=fst.kDelta,
-                  map_type=b"identity",
-                  double power=1.,
-                  weight=None):
+cpdef Fst arcmap(Fst ifst,
+                 float delta=fst.kDelta,
+                 map_type=b"identity",
+                 double power=1.,
+                 weight=None):
   """
   arcmap(ifst, delta=0.0009765625, map_type="identity", power=1., weight=None)
 
@@ -3438,10 +3482,10 @@ cpdef _Fst arcmap(_Fst ifst,
   return _map(ifst, delta, map_type, power, weight)
 
 
-cpdef _MutableFst compose(_Fst ifst1,
-                          _Fst ifst2,
-                          compose_filter=b"auto",
-                          bool connect=True):
+cpdef MutableFst compose(Fst ifst1,
+                         Fst ifst2,
+                         compose_filter=b"auto",
+                         bool connect=True):
   """
   compose(ifst1, ifst2, compose_filter="auto", connect=True)
 
@@ -3474,7 +3518,7 @@ cpdef _MutableFst compose(_Fst ifst1,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _Fst convert(_Fst ifst, fst_type=b""):
+cpdef Fst convert(Fst ifst, fst_type=b""):
   """
   convert(ifst, fst_type="")
 
@@ -3500,13 +3544,13 @@ cpdef _Fst convert(_Fst ifst, fst_type=b""):
   return _init_XFst(tfst.release())
 
 
-cpdef _MutableFst determinize(_Fst ifst,
-                              float delta=fst.kShortestDelta,
-                              det_type=b"functional",
-                              int64 nstate=fst.kNoStateId,
-                              int64 subsequential_label=0,
-                              weight=None,
-                              bool increment_subsequential_label=False):
+cpdef MutableFst determinize(Fst ifst,
+                             float delta=fst.kShortestDelta,
+                             det_type=b"functional",
+                             int64 nstate=fst.kNoStateId,
+                             int64 subsequential_label=0,
+                             weight=None,
+                             bool increment_subsequential_label=False):
   """
   determinize(ifst, delta=1e-6, det_type="functional",
               nstate=NO_STATE_ID, subsequential_label=0, weight=None,
@@ -3559,10 +3603,10 @@ cpdef _MutableFst determinize(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst difference(_Fst ifst1,
-                             _Fst ifst2,
-                             compose_filter=b"auto",
-                             bool connect=True):
+cpdef MutableFst difference(Fst ifst1,
+                            Fst ifst2,
+                            compose_filter=b"auto",
+                            bool connect=True):
   """
   difference(ifst1, ifst2, compose_filter="auto", connect=True)
 
@@ -3596,11 +3640,11 @@ cpdef _MutableFst difference(_Fst ifst1,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst disambiguate(_Fst ifst,
-                               float delta=fst.kDelta,
-                               int64 nstate=fst.kNoStateId,
-                               int64 subsequential_label=0,
-                               weight=None):
+cpdef MutableFst disambiguate(Fst ifst,
+                              float delta=fst.kDelta,
+                              int64 nstate=fst.kNoStateId,
+                              int64 subsequential_label=0,
+                              weight=None):
   """
   disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,
                subsequential_label=0, weight=None):
@@ -3638,7 +3682,7 @@ cpdef _MutableFst disambiguate(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):
+cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):
   """
   epsnormalize(ifst, eps_norm_output=False)
 
@@ -3667,7 +3711,7 @@ cpdef _MutableFst epsnormalize(_Fst ifst, bool eps_norm_output=False):
   return _init_MutableFst(tfst.release())
 
 
-cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
+cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
   """
   equal(ifst1, ifst2, delta=0.0009765625)
 
@@ -3688,7 +3732,7 @@ cpdef bool equal(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)
 
 
-cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:
+cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
   """
   equivalent(ifst1, ifst2, delta=0.0009765625)
 
@@ -3709,10 +3753,10 @@ cpdef bool equivalent(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta) except *:
   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)
 
 
-cpdef _MutableFst intersect(_Fst ifst1,
-                            _Fst ifst2,
-                            compose_filter=b"auto",
-                            bool connect=True):
+cpdef MutableFst intersect(Fst ifst1,
+                           Fst ifst2,
+                           compose_filter=b"auto",
+                           bool connect=True):
   """
   intersect(ifst1, ifst2, compose_filter="auto", connect=True)
 
@@ -3744,7 +3788,7 @@ cpdef _MutableFst intersect(_Fst ifst1,
   return _init_MutableFst(tfst.release())
 
 
-cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
+cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
   """
   isomorphic(ifst1, ifst2, delta=0.0009765625)
 
@@ -3768,10 +3812,10 @@ cpdef bool isomorphic(_Fst ifst1, _Fst ifst2, float delta=fst.kDelta):
   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)
 
 
-cpdef _MutableFst prune(_Fst ifst,
-                        float delta=fst.kDelta,
-                        int64 nstate=fst.kNoStateId,
-                        weight=None):
+cpdef MutableFst prune(Fst ifst,
+                       float delta=fst.kDelta,
+                       int64 nstate=fst.kNoStateId,
+                       weight=None):
   """
   prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)
 
@@ -3799,13 +3843,13 @@ cpdef _MutableFst prune(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst push(_Fst ifst,
-                       float delta=fst.kDelta,
-                       bool push_weights=False,
-                       bool push_labels=False,
-                       bool remove_common_affix=False,
-                       bool remove_total_weight=False,
-                       bool to_final=False):
+cpdef MutableFst push(Fst ifst,
+                      float delta=fst.kDelta,
+                      bool push_weights=False,
+                      bool push_labels=False,
+                      bool remove_common_affix=False,
+                      bool remove_total_weight=False,
+                      bool to_final=False):
   """
   push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,
        remove_common_affix=False, remove_total_weight=False, to_final=False)
@@ -3841,7 +3885,6 @@ cpdef _MutableFst push(_Fst ifst,
   Returns:
     An equivalent pushed FST.
   """
-  # This is copied, almost verbatim, from ./fstpush.cc.
   cdef unique_ptr[fst.VectorFstClass] tfst
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   cdef uint8 flags = fst.GetPushFlags(push_weights,
@@ -3856,8 +3899,8 @@ cpdef _MutableFst push(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef bool randequivalent(_Fst ifst1,
-                          _Fst ifst2,
+cpdef bool randequivalent(Fst ifst1,
+                          Fst ifst2,
                           int32 npath=1,
                           float delta=fst.kDelta,
                           time_t seed=0,
@@ -3907,13 +3950,13 @@ cpdef bool randequivalent(_Fst ifst1,
                             deref(opts))
 
 
-cpdef _MutableFst randgen(_Fst ifst,
-                          int32 npath=1,
-                          time_t seed=0,
-                          select=b"uniform",
-                          int32 max_length=INT32_MAX,
-                          bool weighted=False,
-                          bool remove_total_weight=False):
+cpdef MutableFst randgen(Fst ifst,
+                         int32 npath=1,
+                         time_t seed=0,
+                         select=b"uniform",
+                         int32 max_length=INT32_MAX,
+                         bool weighted=False,
+                         bool remove_total_weight=False):
   """
   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
           weighted=False, remove_total_weight=False)
@@ -3958,11 +4001,11 @@ cpdef _MutableFst randgen(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst replace(pairs,
-                          call_arc_labeling=b"input",
-                          return_arc_labeling=b"neither",
-                          bool epsilon_on_replace=False,
-                          int64 return_label=0):
+cpdef MutableFst replace(pairs,
+                         call_arc_labeling=b"input",
+                         return_arc_labeling=b"neither",
+                         bool epsilon_on_replace=False,
+                         int64 return_label=0):
   """
   replace(pairs, call_arc_labeling="input", return_arc_labeling="neither",
           epsilon_on_replace=False, return_label=0)
@@ -4001,7 +4044,7 @@ cpdef _MutableFst replace(pairs,
   """
   cdef vector[fst.LabelFstClassPair] _pairs
   cdef int64 label
-  cdef _Fst pfst
+  cdef Fst pfst
   for (label, pfst) in pairs:
     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
   cdef unique_ptr[fst.VectorFstClass] tfst
@@ -4018,7 +4061,7 @@ cpdef _MutableFst replace(pairs,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):
+cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):
   """
   reverse(ifst, require_superinitial=True)
 
@@ -4046,7 +4089,7 @@ cpdef _MutableFst reverse(_Fst ifst, bool require_superinitial=True):
 # Pure C++ helper for shortestdistance.
 
 
-cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
+cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
                                                 float delta=fst.kShortestDelta,
                                                 int64 nstate=fst.kNoStateId,
                                                 queue_type=b"auto",
@@ -4070,7 +4113,7 @@ cdef vector[fst.WeightClass] *_shortestdistance(_Fst ifst,
   return distance.release()
 
 
-def shortestdistance(_Fst ifst,
+def shortestdistance(Fst ifst,
                      float delta=fst.kShortestDelta,
                      int64 nstate=fst.kNoStateId,
                      queue_type=b"auto",
@@ -4107,13 +4150,13 @@ def shortestdistance(_Fst ifst,
   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]
 
 
-cpdef _MutableFst shortestpath(_Fst ifst,
-                               float delta=fst.kShortestDelta,
-                               int32 nshortest=1,
-                               int64 nstate=fst.kNoStateId,
-                               queue_type=b"auto",
-                               bool unique=False,
-                               weight=None):
+cpdef MutableFst shortestpath(Fst ifst,
+                              float delta=fst.kShortestDelta,
+                              int32 nshortest=1,
+                              int64 nstate=fst.kNoStateId,
+                              queue_type=b"auto",
+                              bool unique=False,
+                              weight=None):
   """
   shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,
                queue_type="auto", unique=False, weight=None)
@@ -4159,7 +4202,7 @@ cpdef _MutableFst shortestpath(_Fst ifst,
   return _init_MutableFst(tfst.release())
 
 
-cpdef _Fst statemap(_Fst ifst, map_type):
+cpdef Fst statemap(Fst ifst, map_type):
   """
   state_map(ifst, map_type)
 
@@ -4185,7 +4228,7 @@ cpdef _Fst statemap(_Fst ifst, map_type):
   return _map(ifst, fst.kDelta, map_type, 1., None)
 
 
-cpdef _MutableFst synchronize(_Fst ifst):
+cpdef MutableFst synchronize(Fst ifst):
   """
   synchronize(ifst)
 
@@ -4213,7 +4256,7 @@ cpdef _MutableFst synchronize(_Fst ifst):
 ## Compiler.
 
 
-cdef class Compiler(object):
+cdef class Compiler:
 
   """
   Compiler(fst_type="vector", arc_type="standard", isymbols=None,
@@ -4280,20 +4323,20 @@ cdef class Compiler(object):
     self._arc_type = tostring(arc_type)
     self._isymbols = NULL
     if isymbols is not None:
-      self._isymbols = isymbols._table
+      self._isymbols = isymbols._raw_ptr_or_raise()
     self._osymbols = NULL
     if osymbols is not None:
-      self._osymbols = osymbols._table
+      self._osymbols = osymbols._raw_ptr_or_raise()
     self._ssymbols = NULL
     if ssymbols is not None:
-      self._ssymbols = ssymbols._table
+      self._ssymbols = ssymbols._raw_ptr_or_raise()
     self._acceptor = acceptor
     self._keep_isymbols = keep_isymbols
     self._keep_osymbols = keep_osymbols
     self._keep_state_numbering = keep_state_numbering
     self._allow_negative_labels = allow_negative_labels
 
-  cpdef _Fst compile(self):
+  cpdef Fst compile(self):
     """
     compile()
 
@@ -4350,7 +4393,7 @@ cdef class Compiler(object):
 ## FarReader and FarWriter.
 
 
-cdef class FarReader(object):
+cdef class FarReader:
 
   """
   (No constructor.)
@@ -4436,7 +4479,7 @@ cdef class FarReader(object):
   cpdef string far_type(self):
     return fst.GetFarTypeString(self._reader.get().Type())
 
-  cpdef bool find(self, key) except *:
+  cpdef bool find(self, key):
     """
     find(self, key)
 
@@ -4451,7 +4494,7 @@ cdef class FarReader(object):
     """
     return self._reader.get().Find(tostring(key))
 
-  cpdef _Fst get_fst(self):
+  cpdef Fst get_fst(self):
     """
     get_fst(self)
 
@@ -4460,8 +4503,7 @@ cdef class FarReader(object):
     Returns:
       A copy of the FST at the current position.
     """
-    return _init_XFst(new fst.FstClass(
-        deref(self._reader.get().GetFstClass())))
+    return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
 
   cpdef string get_key(self):
     """
@@ -4497,7 +4539,7 @@ cdef class FarReader(object):
       raise KeyError(key)
 
 
-cdef class FarWriter(object):
+cdef class FarWriter:
 
   """
   (No constructor.)
@@ -4562,7 +4604,7 @@ cdef class FarWriter(object):
   cdef void close(self):
     self._writer.reset()
 
-  cpdef void add(self, key, _Fst ifst) except *:
+  cpdef void add(self, key, Fst ifst) except *:
     """
     add(self, key, ifst)
 
@@ -4576,16 +4618,12 @@ cdef class FarWriter(object):
       ifst: The FST to write to the FAR.
 
     Raises:
-      FstArgError: Key out of order.
       FstOpError: Incompatible or invalid arc type.
     """
     # 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)):
       raise FstOpError("Incompatible or invalid arc type")
-    # An error here usually indicates a key out of order.
-    if self._writer.get().Error():
-      raise FstArgError("Key out of order")
 
   cpdef string arc_type(self):
     """
@@ -4615,7 +4653,7 @@ cdef class FarWriter(object):
     return fst.GetFarTypeString(self._writer.get().Type())
 
   # Dictionary-like assignment.
-  def __setitem__(self, key, _Fst fst):
+  def __setitem__(self, key, Fst fst):
     self.add(key, fst)
 
 
diff --git a/src/extensions/python/utility.pxd b/src/extensions/python/utility.pxd
new file mode 100644 (file)
index 0000000..c9db544
--- /dev/null
@@ -0,0 +1,29 @@
+# See www.openfst.org for extensive documentation on this weighted
+# finite-state transducer library.
+
+
+#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>
+    #include <utility>
+
+    namespace fst {
+
+    template <typename T>
+    inline typename std::remove_reference<T>::type &&move(T &t) {
+        return std::move(t);
+    }
+
+    template <typename T>
+    inline typename std::remove_reference<T>::type &&move(T &&t) {
+        return std::move(t);
+    }
+
+    }  // namespace fst
+    """
+    cdef T move[T](T)
index 2eae237..9538318 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 18:0:0
+libfstspecial_la_LDFLAGS = -version-info 19:0:0
 
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
index c20d421..97e9d10 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 18:0:0
+libfstspecial_la_LDFLAGS = -version-info 19:0:0
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
 rho_fst_la_SOURCES = rho-fst.cc
index b503830..1bdebd9 100644 (file)
@@ -1,7 +1,6 @@
 if HAVE_COMPRESS
 compress_include_headers = fst/extensions/compress/compress.h \
-fst/extensions/compress/compressscript.h fst/extensions/compress/gzfile.h \
-fst/extensions/compress/elias.h
+fst/extensions/compress/compressscript.h fst/extensions/compress/elias.h
 endif
 
 if HAVE_FAR
index 356e6c6..66140a3 100644 (file)
@@ -157,7 +157,6 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/verify.h fst/visit.h fst/weight.h \
        fst/extensions/compress/compress.h \
        fst/extensions/compress/compressscript.h \
-       fst/extensions/compress/gzfile.h \
        fst/extensions/compress/elias.h \
        fst/extensions/far/compile-strings.h \
        fst/extensions/far/create.h fst/extensions/far/equal.h \
@@ -405,8 +404,7 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 @HAVE_COMPRESS_TRUE@compress_include_headers = fst/extensions/compress/compress.h \
-@HAVE_COMPRESS_TRUE@fst/extensions/compress/compressscript.h fst/extensions/compress/gzfile.h \
-@HAVE_COMPRESS_TRUE@fst/extensions/compress/elias.h
+@HAVE_COMPRESS_TRUE@fst/extensions/compress/compressscript.h fst/extensions/compress/elias.h
 
 @HAVE_FAR_TRUE@far_include_headers = fst/extensions/far/compile-strings.h \
 @HAVE_FAR_TRUE@fst/extensions/far/create.h fst/extensions/far/equal.h \
index 28220cb..563245a 100644 (file)
@@ -662,7 +662,7 @@ class ReplaceAccumulatorData {
     accumulators_.resize(fst_tuples.size());
     for (Label i = 0; i < accumulators_.size(); ++i) {
       if (!accumulators_[i]) {
-        accumulators_[i].reset(new Accumulator());
+        accumulators_[i] = fst::make_unique<Accumulator>();
         accumulators_[i]->Init(*(fst_tuples[i].second));
       }
       fst_array_.emplace_back(fst_tuples[i].second->Copy());
@@ -874,7 +874,7 @@ class SafeReplaceAccumulator {
     ArcIteratorPtr(const ArcIteratorPtr &copy) {}
 
     void Set(const Fst<Arc> &fst, StateId state_id) {
-      ptr_.reset(new ArcIterator<Fst<Arc>>(fst, state_id));
+      ptr_ = fst::make_unique<ArcIterator<Fst<Arc>>>(fst, state_id);
     }
 
     ArcIterator<Fst<Arc>> *get() { return ptr_.get(); }
index 92dd5d5..f6da8d3 100644 (file)
@@ -94,6 +94,7 @@ namespace internal {
 template <class FST, class T>
 class AddOnImpl : public FstImpl<typename FST::Arc> {
  public:
+  using FstType = FST;
   using Arc = typename FST::Arc;
   using Label = typename Arc::Label;
   using StateId = typename Arc::StateId;
index d39809d..4fb0d4f 100644 (file)
@@ -635,6 +635,26 @@ inline void ArcMapFst<A, B, C>::InitStateIterator(
   data->base = new StateIterator<ArcMapFst<A, B, C>>(*this);
 }
 
+// Constructs and returns an ArcMapFst.  This allows constructing ArcMapFsts
+// without specifying all the types. The template argument is typically
+// not specified, so a call looks like: MakeArcMapFst(fst, Mapper(...)).
+template <class ArcMapper>
+ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc, ArcMapper>
+MakeArcMapFst(const Fst<typename ArcMapper::FromArc> &fst,
+              const ArcMapper &mapper) {
+  return ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
+                   ArcMapper>(fst, mapper);
+}
+
+// Constructs and returns an ArcMapFst.  As above, but using the
+// ArcMapFst(..., ArcMapper *) constructor.
+template <class ArcMapper>
+ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc, ArcMapper>
+MakeArcMapFst(const Fst<typename ArcMapper::FromArc> &fst, ArcMapper *mapper) {
+  return ArcMapFst<typename ArcMapper::FromArc, typename ArcMapper::ToArc,
+                   ArcMapper>(fst, mapper);
+}
+
 // Utility Mappers.
 
 // Mapper that returns its input.
index b9e07f6..9d18cfa 100644 (file)
@@ -59,6 +59,8 @@ struct ArcTpl {
 using StdArc = ArcTpl<TropicalWeight>;
 using LogArc = ArcTpl<LogWeight>;
 using Log64Arc = ArcTpl<Log64Weight>;
+using RealArc = ArcTpl<RealWeight>;
+using Real64Arc = ArcTpl<Real64Weight>;
 using SignedLogArc = ArcTpl<SignedLogWeight>;
 using SignedLog64Arc = ArcTpl<SignedLog64Weight>;
 using MinMaxArc = ArcTpl<MinMaxWeight>;
index 270362a..d74c16a 100644 (file)
@@ -45,24 +45,24 @@ namespace fst {
 // };
 
 // An implementation using a hash map for the entry to ID mapping. H is the
-// hash function and E is the equality function. If passed to the constructor,
-// ownership is given to this class.
+// hash function and E is the equality function.
 template <class I, class T, class H, class E = std::equal_to<T>>
 class HashBiTable {
  public:
-  // Reserves space for table_size elements. If passing H and E to the
-  // constructor, this class owns them.
-  explicit HashBiTable(size_t table_size = 0, H *h = nullptr, E *e = nullptr) :
-      hash_func_(h ? h : new H()), hash_equal_(e ? e : new E()),
-      entry2id_(table_size, *hash_func_, *hash_equal_) {
+  // Reserves space for table_size elements.
+  explicit HashBiTable(size_t table_size = 0, const H &h = H(),
+                       const E &e = E())
+      : hash_func_(h),
+        hash_equal_(e),
+        entry2id_(table_size, hash_func_, hash_equal_) {
     if (table_size) id2entry_.reserve(table_size);
   }
 
   HashBiTable(const HashBiTable<I, T, H, E> &table)
-      : hash_func_(new H(*table.hash_func_)),
-        hash_equal_(new E(*table.hash_equal_)),
+      : hash_func_(table.hash_func_),
+        hash_equal_(table.hash_equal_),
         entry2id_(table.entry2id_.begin(), table.entry2id_.end(),
-                  table.entry2id_.size(), *hash_func_, *hash_equal_),
+                  table.entry2id_.size(), hash_func_, hash_equal_),
         id2entry_(table.id2entry_) {}
 
   I FindId(const T &entry, bool insert = true) {
@@ -89,8 +89,8 @@ class HashBiTable {
   }
 
  private:
-  std::unique_ptr<H> hash_func_;
-  std::unique_ptr<E> hash_equal_;
+  H hash_func_;
+  E hash_equal_;
   std::unordered_map<T, I, H, E> entry2id_;
   std::vector<T> id2entry_;
 };
@@ -111,8 +111,7 @@ struct HashSet : public std::unordered_set<K, H, E, PoolAllocator<K>> {
 // holds keys which are either the ID or kCurrentKey. These keys can be mapped
 // to entries either by looking up in the entry vector or, if kCurrentKey, in
 // current_entry_. The hash and key equality functions map to entries first. H
-// is the hash function and E is the equality function. If passed to the
-// constructor, ownership is given to this class.
+// is the hash function and E is the equality function.
 template <class I, class T, class H, class E = std::equal_to<T>,
           HSType HS = HS_FLAT>
 class CompactHashBiTable {
@@ -122,20 +121,22 @@ class CompactHashBiTable {
   friend class HashFunc;
   friend class HashEqual;
 
-  // Reserves space for table_size elements. If passing H and E to the
-  // constructor, this class owns them.
-  explicit CompactHashBiTable(size_t table_size = 0, H *h = nullptr,
-                              E *e = nullptr) :
-        hash_func_(h ? h : new H()), hash_equal_(e ? e : new E()),
-        compact_hash_func_(*this), compact_hash_equal_(*this),
+  // Reserves space for table_size elements.
+  explicit CompactHashBiTable(size_t table_size = 0, const H &h = H(),
+                              const E &e = E())
+      : hash_func_(h),
+        hash_equal_(e),
+        compact_hash_func_(*this),
+        compact_hash_equal_(*this),
         keys_(table_size, compact_hash_func_, compact_hash_equal_) {
     if (table_size) id2entry_.reserve(table_size);
   }
 
   CompactHashBiTable(const CompactHashBiTable<I, T, H, E, HS> &table)
-      : hash_func_(new H(*table.hash_func_)),
-        hash_equal_(new E(*table.hash_equal_)),
-        compact_hash_func_(*this), compact_hash_equal_(*this),
+      : hash_func_(table.hash_func_),
+        hash_equal_(table.hash_equal_),
+        compact_hash_func_(*this),
+        compact_hash_equal_(*this),
         keys_(table.keys_.size(), compact_hash_func_, compact_hash_equal_),
         id2entry_(table.id2entry_) {
     keys_.insert(table.keys_.begin(), table.keys_.end());
@@ -194,7 +195,7 @@ class CompactHashBiTable {
 
     size_t operator()(I k) const {
       if (k >= kCurrentKey) {
-        return (*ht_->hash_func_)(ht_->Key2Entry(k));
+        return (ht_->hash_func_)(ht_->Key2Entry(k));
       } else {
         return 0;
       }
@@ -212,7 +213,7 @@ class CompactHashBiTable {
       if (k1 == k2) {
         return true;
       } else if (k1 >= kCurrentKey && k2 >= kCurrentKey) {
-        return (*ht_->hash_equal_)(ht_->Key2Entry(k1), ht_->Key2Entry(k2));
+        return (ht_->hash_equal_)(ht_->Key2Entry(k1), ht_->Key2Entry(k2));
       } else {
         return false;
       }
@@ -232,8 +233,8 @@ class CompactHashBiTable {
     }
   }
 
-  std::unique_ptr<H> hash_func_;
-  std::unique_ptr<E> hash_equal_;
+  H hash_func_;
+  E hash_equal_;
   HashFunc compact_hash_func_;
   HashEqual compact_hash_equal_;
   KeyHashSet keys_;
@@ -247,24 +248,20 @@ constexpr I CompactHashBiTable<I, T, H, E, HS>::kCurrentKey;
 // An implementation using a vector for the entry to ID mapping. It is passed a
 // function object FP that should fingerprint entries uniquely to an integer
 // that can used as a vector index. Normally, VectorBiTable constructs the FP
-// object. The user can instead pass in this object; in that case, VectorBiTable
-// takes its ownership.
+// object. The user can instead pass in this object.
 template <class I, class T, class FP>
 class VectorBiTable {
  public:
-  // Reserves table_size cells of space. If passing FP argument to the
-  // constructor, this class owns it.
-  explicit VectorBiTable(FP *fp = nullptr, size_t table_size = 0) :
-      fp_(fp ? fp : new FP()) {
+  // Reserves table_size cells of space.
+  explicit VectorBiTable(const FP &fp = FP(), size_t table_size = 0) : fp_(fp) {
     if (table_size) id2entry_.reserve(table_size);
   }
 
   VectorBiTable(const VectorBiTable<I, T, FP> &table)
-      : fp_(new FP(*table.fp_)), fp2id_(table.fp2id_),
-        id2entry_(table.id2entry_) {}
+      : fp_(table.fp_), fp2id_(table.fp2id_), id2entry_(table.id2entry_) {}
 
   I FindId(const T &entry, bool insert = true) {
-    ssize_t fp = (*fp_)(entry);
+    ssize_t fp = (fp_)(entry);
     if (fp >= fp2id_.size()) fp2id_.resize(fp + 1);
     I &id_ref = fp2id_[fp];
     if (id_ref == 0) {  // T not found.
@@ -282,10 +279,10 @@ class VectorBiTable {
 
   I Size() const { return id2entry_.size(); }
 
-  const FP &Fingerprint() const { return *fp_; }
+  const FP &Fingerprint() const { return fp_; }
 
  private:
-  std::unique_ptr<FP> fp_;
+  FP fp_;
   std::vector<I> fp2id_;
   std::vector<T> id2entry_;
 };
@@ -295,32 +292,40 @@ class VectorBiTable {
 // fingerprinting functor FP returns a unique fingerprint for each entry to be
 // hashed in the vector (these need to be suitable for indexing in a vector).
 // The hash functor H is used when hashing entry into the compact hash table.
-// If passed to the constructor, ownership is given to this class.
 template <class I, class T, class S, class FP, class H, HSType HS = HS_DENSE>
 class VectorHashBiTable {
  public:
   friend class HashFunc;
   friend class HashEqual;
 
-  explicit VectorHashBiTable(S *s, FP *fp, H *h, size_t vector_size = 0,
+  explicit VectorHashBiTable(const S &s = S(), const FP &fp = FP(),
+                             const H &h = H(), size_t vector_size = 0,
                              size_t entry_size = 0)
-      : selector_(s), fp_(fp), h_(h), hash_func_(*this), hash_equal_(*this),
+      : selector_(s),
+        fp_(fp),
+        h_(h),
+        hash_func_(*this),
+        hash_equal_(*this),
         keys_(0, hash_func_, hash_equal_) {
     if (vector_size) fp2id_.reserve(vector_size);
     if (entry_size) id2entry_.reserve(entry_size);
   }
 
   VectorHashBiTable(const VectorHashBiTable<I, T, S, FP, H, HS> &table)
-      : selector_(new S(table.s_)), fp_(new FP(*table.fp_)),
-        h_(new H(*table.h_)), id2entry_(table.id2entry_),
-        fp2id_(table.fp2id_), hash_func_(*this), hash_equal_(*this),
+      : selector_(table.s_),
+        fp_(table.fp_),
+        h_(table.h_),
+        id2entry_(table.id2entry_),
+        fp2id_(table.fp2id_),
+        hash_func_(*this),
+        hash_equal_(*this),
         keys_(table.keys_.size(), hash_func_, hash_equal_) {
     keys_.insert(table.keys_.begin(), table.keys_.end());
   }
 
   I FindId(const T &entry, bool insert = true) {
-    if ((*selector_)(entry)) {  // Uses the vector if selector_(entry) == true.
-      uint64 fp = (*fp_)(entry);
+    if ((selector_)(entry)) {  // Uses the vector if selector_(entry) == true.
+      uint64 fp = (fp_)(entry);
       if (fp2id_.size() <= fp) fp2id_.resize(fp + 1, 0);
       if (fp2id_[fp] == 0) {  // T not found.
         if (insert) {         // Stores and assigns a new ID.
@@ -353,11 +358,11 @@ class VectorHashBiTable {
 
   I Size() const { return id2entry_.size(); }
 
-  const S &Selector() const { return *selector_; }
+  const S &Selector() const { return selector_; }
 
-  const FP &Fingerprint() const { return *fp_; }
+  const FP &Fingerprint() const { return fp_; }
 
-  const H &Hash() const { return *h_; }
+  const H &Hash() const { return h_; }
 
  private:
   static constexpr I kCurrentKey = -1;
@@ -369,7 +374,7 @@ class VectorHashBiTable {
 
     size_t operator()(I k) const {
       if (k >= kCurrentKey) {
-        return (*(ht_->h_))(ht_->Key2Entry(k));
+        return (ht_->h_)(ht_->Key2Entry(k));
       } else {
         return 0;
       }
@@ -405,9 +410,9 @@ class VectorHashBiTable {
     }
   }
 
-  std::unique_ptr<S> selector_;  // True if entry hashed into vector.
-  std::unique_ptr<FP> fp_;       // Fingerprint used for hashing into vector.
-  std::unique_ptr<H> h_;         // Hash funcion used for hashing into hash_set.
+  S selector_;  // True if entry hashed into vector.
+  FP fp_;       // Fingerprint used for hashing into vector.
+  H h_;         // Hash funcion used for hashing into hash_set.
 
   std::vector<T> id2entry_;  // Maps state IDs to entry.
   std::vector<I> fp2id_;     // Maps entry fingerprints to IDs.
index d0f9560..df85739 100644 (file)
@@ -64,11 +64,15 @@ struct CompactFstOptions : public CacheOptions {
 //   class State {
 //    public:
 //     State();  // Required, corresponds to kNoStateId.
-//     State(const Compactor *c, StateId s);  // Accessor for StateId 's'.
+//     // This constructor may, of course, also take a const Compactor *
+//     // for the first argument.  It is recommended to use const Compactor *
+//     // if possible, but this can be Compactor * if necessary.
+//     State(Compactor *c, StateId s);  // Accessor for StateId 's'.
 //     StateId GetStateId() const;
 //     Weight Final() const;
 //     size_t NumArcs() const;
 //     // Gets the 'i'th arc for the state. Requires i < NumArcs().
+//     // Flags are a bitmask of the kArc*Value flags that ArcIterator uses.
 //     Arc GetArc(size_t i, uint8 flags) const;
 //   };
 //
@@ -102,7 +106,7 @@ struct CompactFstOptions : public CacheOptions {
 
 // Old ArcCompactor Interface:
 //
-// This interface is not deprecated; it, along with DefaultCompactStore and
+// This interface is not deprecated; it, along with CompactArcStore and
 // other Stores that implement its interface, is simply more constrained
 // by essentially forcing the implementation to use an index array
 // and an arc array, but giving flexibility in how those are implemented.
@@ -181,8 +185,8 @@ struct CompactFstOptions : public CacheOptions {
 //   FSTERROR() << "Compactor: No default constructor";
 // }
 
-// Default implementation data for DefaultCompactor.  Only old-style
-// ArcCompactors are supported because the DefaultCompactStore constructors
+// Default implementation data for CompactArcCompactor.  Only old-style
+// ArcCompactors are supported because the CompactArcStore constructors
 // use the old API.
 //
 // DefaultCompact store is thread-compatible, but not thread-safe.
@@ -208,33 +212,32 @@ struct CompactFstOptions : public CacheOptions {
 //
 // The unsigned type U is used to represent indices into the compacts_ array.
 template <class Element, class Unsigned>
-class DefaultCompactStore {
+class CompactArcStore {
  public:
-  DefaultCompactStore() = default;
+  CompactArcStore() = default;
 
   // Makes a thread-safe copy. O(1).
-  DefaultCompactStore(const DefaultCompactStore &) = default;
+  CompactArcStore(const CompactArcStore &) = default;
 
   template <class Arc, class ArcCompactor>
-  DefaultCompactStore(const Fst<Arc> &fst, const ArcCompactor &arc_compactor);
+  CompactArcStore(const Fst<Arc> &fst, const ArcCompactor &arc_compactor);
 
   template <class Iterator, class ArcCompactor>
-  DefaultCompactStore(const Iterator begin, const Iterator end,
-                      const ArcCompactor &arc_compactor);
+  CompactArcStore(const Iterator begin, const Iterator end,
+                  const ArcCompactor &arc_compactor);
 
-  ~DefaultCompactStore() = default;
+  ~CompactArcStore() = default;
 
   template <class ArcCompactor>
-  static DefaultCompactStore *Read(std::istream &strm,
-                                   const FstReadOptions &opts,
-                                   const FstHeader &hdr,
-                                   const ArcCompactor &arc_compactor);
+  static CompactArcStore *Read(std::istream &strm, const FstReadOptions &opts,
+                               const FstHeader &hdr,
+                               const ArcCompactor &arc_compactor);
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const;
 
   // Returns the starting index in 'compacts_' of the transitions
   // for state 'i'.  See class-level comment for further details.
-  // Requires that the DefaultCompactStore was constructed with a
+  // Requires that the CompactArcStore was constructed with a
   // variable out-degree compactor.  Requires 0 <= i <= NumStates().
   // By convention, States(NumStates()) == NumCompacts().
   Unsigned States(ssize_t i) const { return states_[i]; }
@@ -272,7 +275,7 @@ class DefaultCompactStore {
 
 template <class Element, class Unsigned>
 template <class Arc, class ArcCompactor>
-DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
+CompactArcStore<Element, Unsigned>::CompactArcStore(
     const Fst<Arc> &fst, const ArcCompactor &arc_compactor) {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
@@ -286,24 +289,24 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
     if (fst.Final(s) != Weight::Zero()) ++nfinals;
   }
   if (arc_compactor.Size() == -1) {
-    states_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(states_[0]) * (nstates_ + 1)));
+    states_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(states_[0]) * (nstates_ + 1), alignof(decltype(states_[0]))));
     states_ = static_cast<Unsigned *>(states_region_->mutable_data());
     ncompacts_ = narcs_ + nfinals;
-    compacts_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(compacts_[0]) * (ncompacts_)));
+    compacts_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(compacts_[0]) * ncompacts_, alignof(decltype(compacts_[0]))));
     compacts_ = static_cast<Element *>(compacts_region_->mutable_data());
     states_[nstates_] = ncompacts_;
   } else {
     states_ = nullptr;
     ncompacts_ = nstates_ * arc_compactor.Size();
     if ((narcs_ + nfinals) != ncompacts_) {
-      FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
+      FSTERROR() << "CompactArcStore: ArcCompactor incompatible with FST";
       error_ = true;
       return;
     }
-    compacts_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(compacts_[0]) * (ncompacts_)));
+    compacts_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(compacts_[0]) * ncompacts_, alignof(decltype(compacts_[0]))));
     compacts_ = static_cast<Element *>(compacts_region_->mutable_data());
   }
   size_t pos = 0;
@@ -319,13 +322,13 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
       compacts_[pos++] = arc_compactor.Compact(s, aiter.Value());
     }
     if ((arc_compactor.Size() != -1) && (pos != fpos + arc_compactor.Size())) {
-      FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
+      FSTERROR() << "CompactArcStore: ArcCompactor incompatible with FST";
       error_ = true;
       return;
     }
   }
   if (pos != ncompacts_) {
-    FSTERROR() << "DefaultCompactStore: ArcCompactor incompatible with FST";
+    FSTERROR() << "CompactArcStore: ArcCompactor incompatible with FST";
     error_ = true;
     return;
   }
@@ -333,7 +336,7 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
 
 template <class Element, class Unsigned>
 template <class Iterator, class ArcCompactor>
-DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
+CompactArcStore<Element, Unsigned>::CompactArcStore(
     const Iterator begin, const Iterator end,
     const ArcCompactor &arc_compactor) {
   using Arc = typename ArcCompactor::Arc;
@@ -352,7 +355,7 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
       }
     }
     if (ncompacts_ % arc_compactor.Size()) {
-      FSTERROR() << "DefaultCompactStore: Size of input container incompatible"
+      FSTERROR() << "CompactArcStore: Size of input container incompatible"
                  << " with arc compactor";
       error_ = true;
       return;
@@ -360,8 +363,8 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
     if (ncompacts_ == 0) return;
     start_ = 0;
     nstates_ = ncompacts_ / arc_compactor.Size();
-    compacts_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(compacts_[0]) * (ncompacts_)));
+    compacts_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(compacts_[0]) * ncompacts_, alignof(decltype(compacts_[0]))));
     compacts_ = static_cast<Element *>(compacts_region_->mutable_data());
     size_t i = 0;
     Iterator it = begin;
@@ -388,11 +391,11 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
       }
     }
     start_ = 0;
-    compacts_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(compacts_[0]) * (ncompacts_)));
+    compacts_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(compacts_[0]) * ncompacts_, alignof(decltype(compacts_[0]))));
     compacts_ = static_cast<Element *>(compacts_region_->mutable_data());
-    states_region_ = fst::WrapUnique(
-        MappedFile::Allocate(sizeof(states_[0]) * (nstates_ + 1)));
+    states_region_ = fst::WrapUnique(MappedFile::Allocate(
+        sizeof(states_[0]) * (nstates_ + 1), alignof(decltype(states_[0]))));
     states_ = static_cast<Unsigned *>(states_region_->mutable_data());
     states_[nstates_] = ncompacts_;
     size_t i = 0;
@@ -407,7 +410,7 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
       }
     }
     if ((s != nstates_) || (i != ncompacts_)) {
-      FSTERROR() << "DefaultCompactStore: Ill-formed input container";
+      FSTERROR() << "CompactArcStore: Ill-formed input container";
       error_ = true;
       return;
     }
@@ -416,25 +419,23 @@ DefaultCompactStore<Element, Unsigned>::DefaultCompactStore(
 
 template <class Element, class Unsigned>
 template <class ArcCompactor>
-DefaultCompactStore<Element, Unsigned>
-    *DefaultCompactStore<Element, Unsigned>::Read(
-        std::istream &strm, const FstReadOptions &opts, const FstHeader &hdr,
-        const ArcCompactor &arc_compactor) {
-  std::unique_ptr<DefaultCompactStore> data(new DefaultCompactStore);
+CompactArcStore<Element, Unsigned> *CompactArcStore<Element, Unsigned>::Read(
+    std::istream &strm, const FstReadOptions &opts, const FstHeader &hdr,
+    const ArcCompactor &arc_compactor) {
+  std::unique_ptr<CompactArcStore> data(new CompactArcStore);
   data->start_ = hdr.Start();
   data->nstates_ = hdr.NumStates();
   data->narcs_ = hdr.NumArcs();
   if (arc_compactor.Size() == -1) {
     if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && !AlignInput(strm)) {
-      LOG(ERROR) << "DefaultCompactStore::Read: Alignment failed: "
-                 << opts.source;
+      LOG(ERROR) << "CompactArcStore::Read: Alignment failed: " << opts.source;
       return nullptr;
     }
     auto b = (data->nstates_ + 1) * sizeof(Unsigned);
     data->states_region_.reset(MappedFile::Map(
         &strm, opts.mode == FstReadOptions::MAP, opts.source, b));
     if (!strm || !data->states_region_) {
-      LOG(ERROR) << "DefaultCompactStore::Read: Read failed: " << opts.source;
+      LOG(ERROR) << "CompactArcStore::Read: Read failed: " << opts.source;
       return nullptr;
     }
     data->states_ =
@@ -446,15 +447,14 @@ DefaultCompactStore<Element, Unsigned>
                          ? data->states_[data->nstates_]
                          : data->nstates_ * arc_compactor.Size();
   if ((hdr.GetFlags() & FstHeader::IS_ALIGNED) && !AlignInput(strm)) {
-    LOG(ERROR) << "DefaultCompactStore::Read: Alignment failed: "
-               << opts.source;
+    LOG(ERROR) << "CompactArcStore::Read: Alignment failed: " << opts.source;
     return nullptr;
   }
   size_t b = data->ncompacts_ * sizeof(Element);
   data->compacts_region_.reset(
       MappedFile::Map(&strm, opts.mode == FstReadOptions::MAP, opts.source, b));
   if (!strm || !data->compacts_region_) {
-    LOG(ERROR) << "DefaultCompactStore::Read: Read failed: " << opts.source;
+    LOG(ERROR) << "CompactArcStore::Read: Read failed: " << opts.source;
     return nullptr;
   }
   data->compacts_ =
@@ -463,46 +463,45 @@ DefaultCompactStore<Element, Unsigned>
 }
 
 template <class Element, class Unsigned>
-bool DefaultCompactStore<Element, Unsigned>::Write(
+bool CompactArcStore<Element, Unsigned>::Write(
     std::ostream &strm, const FstWriteOptions &opts) const {
   if (states_) {
     if (opts.align && !AlignOutput(strm)) {
-      LOG(ERROR) << "DefaultCompactStore::Write: Alignment failed: "
-                 << opts.source;
+      LOG(ERROR) << "CompactArcStore::Write: Alignment failed: " << opts.source;
       return false;
     }
     strm.write(reinterpret_cast<const char *>(states_),
                (nstates_ + 1) * sizeof(Unsigned));
   }
   if (opts.align && !AlignOutput(strm)) {
-    LOG(ERROR) << "DefaultCompactStore::Write: Alignment failed: "
-               << opts.source;
+    LOG(ERROR) << "CompactArcStore::Write: Alignment failed: " << opts.source;
     return false;
   }
   strm.write(reinterpret_cast<const char *>(compacts_),
              ncompacts_ * sizeof(Element));
   strm.flush();
   if (!strm) {
-    LOG(ERROR) << "DefaultCompactStore::Write: Write failed: " << opts.source;
+    LOG(ERROR) << "CompactArcStore::Write: Write failed: " << opts.source;
     return false;
   }
   return true;
 }
 
 template <class Element, class Unsigned>
-const std::string &DefaultCompactStore<Element, Unsigned>::Type() {
+const std::string &CompactArcStore<Element, Unsigned>::Type() {
   static const std::string *const type = new std::string("compact");
   return *type;
 }
 
-template <class C, class U, class S> class DefaultCompactState;
+template <class C, class U, class S>
+class CompactArcState;
 
 // Wraps an old-style arc compactor and a compact store as a new Fst compactor.
 // The copy constructors of AC and S must make thread-safe copies and should
 // be O(1).
 template <class AC, class U,
-          class S /*= DefaultCompactStore<typename AC::Element, U>*/>
-class DefaultCompactor {
+          class S /*= CompactArcStore<typename AC::Element, U>*/>
+class CompactArcCompactor {
  public:
   using ArcCompactor = AC;
   using Unsigned = U;
@@ -511,33 +510,32 @@ class DefaultCompactor {
   using Arc = typename AC::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using State = DefaultCompactState<AC, U, S>;
+  using State = CompactArcState<AC, U, S>;
   friend State;
 
-  DefaultCompactor()
-      : arc_compactor_(nullptr), compact_store_(nullptr) {}
+  CompactArcCompactor() : arc_compactor_(nullptr), compact_store_(nullptr) {}
 
   // Constructs from Fst.
-  explicit DefaultCompactor(const Fst<Arc> &fst,
-                            ArcCompactor &&arc_compactor = ArcCompactor())
-      : DefaultCompactor(
+  explicit CompactArcCompactor(const Fst<Arc> &fst,
+                               ArcCompactor &&arc_compactor = ArcCompactor())
+      : CompactArcCompactor(
             fst, std::make_shared<ArcCompactor>(std::move(arc_compactor))) {}
 
-  DefaultCompactor(const Fst<Arc> &fst,
-                   std::shared_ptr<ArcCompactor> arc_compactor)
+  CompactArcCompactor(const Fst<Arc> &fst,
+                      std::shared_ptr<ArcCompactor> arc_compactor)
       : arc_compactor_(std::move(arc_compactor)),
         compact_store_(std::make_shared<S>(fst, *arc_compactor_)) {}
 
-  DefaultCompactor(const Fst<Arc> &fst,
-                   std::shared_ptr<DefaultCompactor> compactor)
+  CompactArcCompactor(const Fst<Arc> &fst,
+                      std::shared_ptr<CompactArcCompactor> compactor)
       : arc_compactor_(compactor->arc_compactor_),
         compact_store_(compactor->compact_store_ == nullptr
                            ? std::make_shared<S>(fst, *arc_compactor_)
                            : compactor->compact_store_) {}
 
   // Constructs from CompactStore.
-  DefaultCompactor(std::shared_ptr<ArcCompactor> arc_compactor,
-                   std::shared_ptr<CompactStore> compact_store)
+  CompactArcCompactor(std::shared_ptr<ArcCompactor> arc_compactor,
+                      std::shared_ptr<CompactStore> compact_store)
       : arc_compactor_(std::move(arc_compactor)),
         compact_store_(std::move(compact_store)) {}
 
@@ -564,19 +562,19 @@ class DefaultCompactor {
   // CompactArcFst<...> fst(
   //     std::make_shared<CompactArcFst<...>::Compactor>(b, e));
   template <class Iterator>
-  DefaultCompactor(const Iterator b, const Iterator e,
-                   std::shared_ptr<ArcCompactor> arc_compactor)
+  CompactArcCompactor(const Iterator b, const Iterator e,
+                      std::shared_ptr<ArcCompactor> arc_compactor)
       : arc_compactor_(std::move(arc_compactor)),
         compact_store_(std::make_shared<S>(b, e, *arc_compactor_)) {}
 
   template <class Iterator>
-  DefaultCompactor(const Iterator b, const Iterator e)
-      : DefaultCompactor(b, e, std::make_shared<ArcCompactor>()) {}
+  CompactArcCompactor(const Iterator b, const Iterator e)
+      : CompactArcCompactor(b, e, std::make_shared<ArcCompactor>()) {}
 
   // Copy constructor.  This makes a thread-safe copy, so requires that
-  // The ArcCompactor and CompactStore copy constructores make thread-safe
+  // The ArcCompactor and CompactStore copy constructors make thread-safe
   // copies.
-  DefaultCompactor(const DefaultCompactor &compactor)
+  CompactArcCompactor(const CompactArcCompactor &compactor)
       : arc_compactor_(
             compactor.GetArcCompactor() == nullptr
                 ? nullptr
@@ -587,7 +585,8 @@ class DefaultCompactor {
                                  *compactor.GetCompactStore())) {}
 
   template <class OtherC>
-  explicit DefaultCompactor(const DefaultCompactor<OtherC, U, S> &compactor)
+  explicit CompactArcCompactor(
+      const CompactArcCompactor<OtherC, U, S> &compactor)
       : arc_compactor_(
             compactor.GetArcCompactor() == nullptr
                 ? nullptr
@@ -605,13 +604,14 @@ class DefaultCompactor {
     if (state->GetStateId() != s) state->Set(this, s);
   }
 
-  static DefaultCompactor *Read(std::istream &strm, const FstReadOptions &opts,
-                                const FstHeader &hdr) {
+  static CompactArcCompactor *Read(std::istream &strm,
+                                   const FstReadOptions &opts,
+                                   const FstHeader &hdr) {
     std::shared_ptr<ArcCompactor> arc_compactor(ArcCompactor::Read(strm));
     if (arc_compactor == nullptr) return nullptr;
     std::shared_ptr<S> compact_store(S::Read(strm, opts, hdr, *arc_compactor));
     if (compact_store == nullptr) return nullptr;
-    return new DefaultCompactor(arc_compactor, compact_store);
+    return new CompactArcCompactor(arc_compactor, compact_store);
   }
 
   bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
@@ -651,13 +651,11 @@ class DefaultCompactor {
   const ArcCompactor *GetArcCompactor() const { return arc_compactor_.get(); }
   const CompactStore *GetCompactStore() const { return compact_store_.get(); }
 
-  std::shared_ptr<ArcCompactor> SharedArcCompactor() const {
-    return arc_compactor_;
-  }
+  ArcCompactor *MutableArcCompactor() { return arc_compactor_.get(); }
+  CompactStore *MutableCompactStore() { return compact_store_.get(); }
 
-  std::shared_ptr<CompactStore> SharedCompactStore() const {
-    return compact_store_;
-  }
+  std::shared_ptr<ArcCompactor> SharedArcCompactor() { return arc_compactor_; }
+  std::shared_ptr<CompactStore> SharedCompactStore() { return compact_store_; }
 
   // TODO(allauzen): remove dependencies on this method and make private.
   Arc ComputeArc(StateId s, Unsigned i, uint8 flags) const {
@@ -683,18 +681,18 @@ class DefaultCompactor {
 };
 
 // Default implementation of state attributes accessor class for
-// DefaultCompactor. Use of efficient specialization strongly encouraged.
+// CompactArcCompactor. Use of efficient specialization strongly encouraged.
 template <class ArcCompactor, class U, class S>
-class DefaultCompactState {
+class CompactArcState {
  public:
   using Arc = typename ArcCompactor::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using Compactor = DefaultCompactor<ArcCompactor, U, S>;
+  using Compactor = CompactArcCompactor<ArcCompactor, U, S>;
 
-  DefaultCompactState() = default;
+  CompactArcState() = default;
 
-  DefaultCompactState(const Compactor *compactor, StateId s)
+  CompactArcState(const Compactor *compactor, StateId s)
       : compactor_(compactor),
         s_(s),
         range_(compactor->CompactsRange(s)),
@@ -743,20 +741,20 @@ class DefaultCompactState {
   bool has_final_ = false;
 };
 
-// Specialization for DefaultCompactStore.
+// Specialization for CompactArcStore.
 template <class ArcCompactor, class U>
-class DefaultCompactState<
-    ArcCompactor, U, DefaultCompactStore<typename ArcCompactor::Element, U>> {
+class CompactArcState<ArcCompactor, U,
+                      CompactArcStore<typename ArcCompactor::Element, U>> {
  public:
   using Arc = typename ArcCompactor::Arc;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
-  using CompactStore = DefaultCompactStore<typename ArcCompactor::Element, U>;
-  using Compactor = DefaultCompactor<ArcCompactor, U, CompactStore>;
+  using CompactStore = CompactArcStore<typename ArcCompactor::Element, U>;
+  using Compactor = CompactArcCompactor<ArcCompactor, U, CompactStore>;
 
-  DefaultCompactState() = default;
+  CompactArcState() = default;
 
-  DefaultCompactState(const Compactor *compactor, StateId s)
+  CompactArcState(const Compactor *compactor, StateId s)
       : arc_compactor_(compactor->GetArcCompactor()), s_(s) {
     Init(compactor);
   }
@@ -824,7 +822,7 @@ bool WriteCompactArcFst(
 namespace internal {
 
 // Implementation class for CompactFst, which contains parametrizeable
-// Fst data storage (DefaultCompactStore by default) and Fst cache.
+// Fst data storage (CompactArcStore by default) and Fst cache.
 // C's copy constructor must make a thread-safe copy.
 template <class Arc, class C, class CacheStore = DefaultCacheStore<Arc>>
 class CompactFstImpl
@@ -857,6 +855,10 @@ class CompactFstImpl
     SetProperties(kNullProperties | kStaticProperties);
   }
 
+  // Constructs a CompactFstImpl, creating a new Compactor using
+  // Compactor(fst, compactor); this uses the compactor arg only for optional
+  // information, such as compression level.  See the Compactor interface
+  // description.
   CompactFstImpl(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
                  const CompactFstOptions &opts)
       : ImplBase(opts),
@@ -1014,7 +1016,8 @@ class CompactFstImpl
   }
 
   const Compactor *GetCompactor() const { return compactor_.get(); }
-  std::shared_ptr<Compactor> SharedCompactor() const { return compactor_; }
+  Compactor *MutableCompactor() { return compactor_.get(); }
+  std::shared_ptr<Compactor> SharedCompactor() { return compactor_; }
   void SetCompactor(std::shared_ptr<Compactor> compactor) {
     // TODO(allauzen): is this correct? is this needed?
     // TODO(allauzen): consider removing and forcing this through direct calls
@@ -1098,8 +1101,6 @@ class CompactFst
   using Impl = internal::CompactFstImpl<Arc, Compactor, CacheStore>;
   using Store = CacheStore;  // for CacheArcIterator
 
-  // These iterators do not need to be friends, but allow specializations
-  // of them to have internal access.
   friend class StateIterator<CompactFst>;
   friend class ArcIterator<CompactFst>;
 
@@ -1109,6 +1110,10 @@ class CompactFst
                       const CompactFstOptions &opts = CompactFstOptions())
       : CompactFst(fst, std::make_shared<Compactor>(fst), opts) {}
 
+  // Constructs a CompactFst, creating a new Compactor using
+  // Compactor(fst, compactor); this uses the compactor arg only for optional
+  // information, such as compression level.  See the Compactor interface
+  // description.
   CompactFst(const Fst<Arc> &fst, std::shared_ptr<Compactor> compactor,
              const CompactFstOptions &opts = CompactFstOptions())
       : ImplToExpandedFst<Impl>(
@@ -1116,6 +1121,10 @@ class CompactFst
 
   // Convenience constructor taking a Compactor rvalue ref.  Avoids
   // clutter of make_shared<Compactor> at call site.
+  // Constructs a CompactFst, creating a new Compactor using
+  // Compactor(fst, compactor); this uses the compactor arg only for optional
+  // information, such as compression level.  See the Compactor interface
+  // description.
   CompactFst(const Fst<Arc> &fst, Compactor &&compactor,
              const CompactFstOptions &opts = CompactFstOptions())
       : CompactFst(fst, std::make_shared<Compactor>(std::move(compactor)),
@@ -1328,7 +1337,7 @@ class ArcIterator<CompactFst<Arc, Compactor, CacheStore>> {
   using State = typename Compactor::State;
 
   ArcIterator(const CompactFst<Arc, Compactor, CacheStore> &fst, StateId s)
-      : state_(fst.GetCompactor(), s),
+      : state_(fst.GetMutableImpl()->MutableCompactor(), s),
         pos_(0),
         num_arcs_(state_.NumArcs()),
         flags_(kArcValueFlags) {}
index cc4a6ee..054b703 100644 (file)
@@ -16,7 +16,6 @@
 #include <fst/fst.h>
 #include <fst/test-properties.h>
 
-
 namespace fst {
 
 template <class Arc>
@@ -200,7 +199,8 @@ class ArcIterator<ComplementFst<Arc>> : public ArcIteratorBase<Arc> {
 
   ArcIterator(const ComplementFst<Arc> &fst, StateId s) : s_(s), pos_(0) {
     if (s_ != 0) {
-      aiter_.reset(new ArcIterator<Fst<Arc>>(*fst.GetImpl()->fst_, s - 1));
+      aiter_ =
+          fst::make_unique<ArcIterator<Fst<Arc>>>(*fst.GetImpl()->fst_, s - 1);
     }
   }
 
index fd24990..448ff59 100644 (file)
@@ -16,7 +16,6 @@
 #include <fst/mutable-fst.h>
 #include <fst/union-find.h>
 
-
 namespace fst {
 
 // Finds and returns connected components. Use with Visit().
@@ -196,10 +195,10 @@ inline void SccVisitor<Arc>::InitVisit(const Fst<Arc> &fst) {
   start_ = fst.Start();
   nstates_ = 0;
   nscc_ = 0;
-  dfnumber_.reset(new std::vector<StateId>());
-  lowlink_.reset(new std::vector<StateId>());
-  onstack_.reset(new std::vector<bool>());
-  scc_stack_.reset(new std::vector<StateId>());
+  dfnumber_ = fst::make_unique<std::vector<StateId>>();
+  lowlink_ = fst::make_unique<std::vector<StateId>>();
+  onstack_ = fst::make_unique<std::vector<bool>>();
+  scc_stack_ = fst::make_unique<std::vector<StateId>>();
 }
 
 template <class Arc>
index d27a4d4..61642a5 100644 (file)
@@ -25,7 +25,6 @@
 #include <fst/prune.h>
 #include <fst/test-properties.h>
 
-
 namespace fst {
 
 // Common divisors are used in determinization to compute transition weights.
@@ -975,7 +974,8 @@ void DeterminizeFstImpl<A, G, D, F, T>::Init(const Fst<A> &fst, F *filter) {
       subsequential_label_, increment_subsequential_label_,
       increment_subsequential_label_);
   const FactorWeightFst<ToArc, FactorIterator> factored_fst(det_fsa, fopts);
-  from_fst_.reset(new FromFst(factored_fst, FromMapper(subsequential_label_)));
+  from_fst_ = fst::make_unique<FromFst>(factored_fst,
+                                         FromMapper(subsequential_label_));
 }
 
 }  // namespace internal
index c8f5481..a413524 100644 (file)
@@ -26,7 +26,6 @@
 #include <fst/union-find.h>
 #include <fst/verify.h>
 
-
 namespace fst {
 
 template <class Arc>
@@ -408,7 +407,7 @@ void Disambiguator<Arc>::PreDisambiguate(const ExpandedFst<Arc> &ifst,
 template <class Arc>
 void Disambiguator<Arc>::FindAmbiguities(const ExpandedFst<Arc> &fst) {
   if (fst.Start() == kNoStateId) return;
-  candidates_.reset(new ArcIdMap(ArcIdCompare(head_)));
+  candidates_ = fst::make_unique<ArcIdMap>(ArcIdCompare(head_));
   const auto start_pr = std::make_pair(fst.Start(), fst.Start());
   coreachable_.insert(start_pr);
   queue_.push_back(start_pr);
@@ -449,7 +448,8 @@ void Disambiguator<Arc>::FindAmbiguousPairs(const ExpandedFst<Arc> &fst,
           if (spr.first != spr.second &&
               head_[spr.first] == head_[spr.second]) {
             if (!merge_) {
-              merge_.reset(new UnionFind<StateId>(fst.NumStates(), kNoStateId));
+              merge_ = fst::make_unique<UnionFind<StateId>>(fst.NumStates(),
+                                                             kNoStateId);
               merge_->MakeAllSet(fst.NumStates());
             }
             merge_->Union(spr.first, spr.second);
index e146f5a..e833968 100644 (file)
@@ -34,7 +34,6 @@
 
 #include <fst/cache.h>
 
-
 namespace fst {
 namespace internal {
 
@@ -588,7 +587,7 @@ inline void EditFstImpl<Arc, WrappedFstT, MutableFstT>::DeleteStates() {
   data_->DeleteStates();
   // we are deleting all states, so just forget about pointer to wrapped_
   // and do what default constructor does: set wrapped_ to a new VectorFst
-  wrapped_.reset(new MutableFstT());
+  wrapped_ = fst::make_unique<MutableFstT>();
   const auto new_props =
       DeleteAllStatesProperties(FstImpl<Arc>::Properties(), kStaticProperties);
   FstImpl<Arc>::SetProperties(new_props);
index ffc89c6..abdfcd5 100644 (file)
@@ -25,8 +25,10 @@ class WeightApproxEqual {
  public:
   explicit WeightApproxEqual(float delta) : delta_(delta) {}
 
-  template <class Weight>
-  bool operator()(const Weight &w1, const Weight &w2) const {
+  // We use two weight types to avoid some conflicts caused by
+  // conversions.
+  template <class Weight1, class Weight2>
+  bool operator()(const Weight1 &w1, const Weight2 &w2) const {
     return ApproxEqual(w1, w2, delta_);
   }
 
index 85dfbc9..996d404 100644 (file)
@@ -134,7 +134,7 @@ class NoGcKeepOneExpanderCache {
     auto i = cache_.find(state_id_);
     if (i != cache_.end()) state_ = std::move(i->second);
     if (state_ == nullptr) {
-      state_.reset(new State);
+      state_ = fst::make_unique<State>();
       expander.Expand(state_id_, state_.get());
     }
     return state_.get();
index 768baed..fb22c5c 100644 (file)
@@ -23,7 +23,6 @@
 #include <fst/log.h>
 
 #include <fst/pair-weight.h>
-#include <fst/product-weight.h>
 
 
 namespace fst {
@@ -115,6 +114,37 @@ inline ExpectationWeight<X1, X2> Divide(const ExpectationWeight<X1, X2> &w1,
   return ExpectationWeight<X1, X2>::NoWeight();
 }
 
+// Specialization for enpectation weight
+template <class X1, class X2>
+class Adder<ExpectationWeight<X1, X2>> {
+ public:
+  using Weight = ExpectationWeight<X1, X2>;
+
+  Adder() {}
+
+  explicit Adder(Weight w)
+      : adder1_(w.Value1()),
+        adder2_(w.Value2()) {}
+
+  Weight Add(const Weight &w) {
+    adder1_.Add(w.Value1());
+    adder2_.Add(w.Value2());
+    return Sum();
+  }
+
+  Weight Sum() const { return Weight(adder1_.Sum(), adder2_.Sum()); }
+
+  void Reset(Weight w = Weight::Zero()) {
+    adder1_.Reset(w.Value1());
+    adder2_.Reset(w.Value2());
+  }
+
+ private:
+  Adder<X1> adder1_;
+  Adder<X2> 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.
index 9abfb2b..349300a 100644 (file)
 #include <fst/types.h>
 #include <fst/log.h>
 #include <fst/extensions/compress/elias.h>
-#include <fst/extensions/compress/gzfile.h>
 #include <fst/encode.h>
 #include <fstream>
 #include <fst/fst.h>
 #include <fst/mutable-fst.h>
+#include <fst/queue.h>
 #include <fst/statesort.h>
+#include <fst/visit.h>
 
 namespace fst {
 
 // Identifies stream data as a vanilla compressed FST.
 static const int32 kCompressMagicNumber = 1858869554;
-// Identifies stream data as (probably) a Gzip file accidentally read from a
-// vanilla stream, without gzip support.
-static const int32 kGzipMagicNumber = 0x8b1f;
-// Selects the two most significant bytes.
-constexpr uint32 kGzipMask = 0xffffffff >> 16;
 
 namespace internal {
 
@@ -302,44 +298,33 @@ void Compressor<Arc>::DecodeForCompress(MutableFst<Arc> *fst,
 template <class Arc>
 void Compressor<Arc>::BfsOrder(const ExpandedFst<Arc> &fst,
                                std::vector<StateId> *order) {
-  StateId bfs_visit_number = 0;
-  std::queue<StateId> states_queue;
-  order->assign(fst.NumStates(), kNoStateId);
-  states_queue.push(fst.Start());
-  (*order)[fst.Start()] = bfs_visit_number++;
-  while (!states_queue.empty()) {
-    for (ArcIterator<Fst<Arc>> aiter(fst, states_queue.front()); !aiter.Done();
-         aiter.Next()) {
-      const auto &arc = aiter.Value();
-      const auto nextstate = arc.nextstate;
-      if ((*order)[nextstate] == kNoStateId) {
-        (*order)[nextstate] = bfs_visit_number++;
-        states_queue.push(nextstate);
-      }
-    }
-    states_queue.pop();
-  }
-  // Handles any unconnected states.
-  while (bfs_visit_number < fst.NumStates()) {
-    StateId unseen_state = 0;
-    for (; unseen_state < fst.NumStates(); ++unseen_state) {
-      if ((*order)[unseen_state] == kNoStateId) break;
-    }
-    states_queue.push(unseen_state);
-    (*order)[unseen_state] = bfs_visit_number++;
-    while (!states_queue.empty()) {
-      for (ArcIterator<Fst<Arc>> aiter(fst, states_queue.front());
-           !aiter.Done(); aiter.Next()) {
-        const auto &arc = aiter.Value();
-        const auto nextstate = arc.nextstate;
-        if ((*order)[nextstate] == kNoStateId) {
-          (*order)[nextstate] = bfs_visit_number++;
-          states_queue.push(nextstate);
-        }
-      }
-      states_queue.pop();
+  class BfsVisitor {
+   public:
+    // Requires order->size() >= fst.NumStates().
+    explicit BfsVisitor(std::vector<StateId> *order) : order_(order) {}
+
+    void InitVisit(const Fst<Arc> &fst) {}
+
+    bool InitState(StateId s, StateId) {
+      order_->at(s) = num_bfs_states_++;
+      return true;
     }
-  }
+
+    bool WhiteArc(StateId s, const Arc &arc) { return true; }
+    bool GreyArc(StateId s, const Arc &arc) { return true; }
+    bool BlackArc(StateId s, const Arc &arc) { return true; }
+    void FinishState(StateId s) {}
+    void FinishVisit() {}
+
+   private:
+    std::vector<StateId> *order_ = nullptr;
+    StateId num_bfs_states_ = 0;
+  };
+
+  order->assign(fst.NumStates(), kNoStateId);
+  BfsVisitor visitor(order);
+  FifoQueue<StateId> queue;
+  Visit(fst, &visitor, &queue, AnyArcFilter<Arc>());
 }
 
 template <class Arc>
@@ -677,15 +662,6 @@ bool Compressor<Arc>::Decompress(std::istream &strm, const std::string &source,
   ReadType(strm, &magic_number);
   if (magic_number != kCompressMagicNumber) {
     LOG(ERROR) << "Decompress: Bad compressed Fst: " << source;
-    // If the most significant two bytes of the magic number match the
-    // gzip magic number, then we are probably reading a gzip file as an
-    // ordinary stream.
-    if ((magic_number & kGzipMask) == kGzipMagicNumber) {
-      LOG(ERROR) << "Decompress: Fst appears to be compressed with Gzip, but "
-                    "gzip decompression was not requested. Try with "
-                    "the --gzip flag"
-                    ".";
-    }
     return false;
   }
   std::unique_ptr<EncodeMapper<Arc>> encoder(
@@ -767,35 +743,18 @@ void Compress(const Fst<Arc> &fst, std::ostream &strm) {
 }
 
 template <class Arc>
-bool Compress(const Fst<Arc> &fst, const std::string &source,
-              const bool gzip = false) {
-  if (gzip) {
-      std::stringstream strm;
-      Compress(fst, strm);
-      OGzFile gzfile(source);
-      if (!gzfile) {
-        LOG(ERROR) << "Compress: Can't open file: "
-                   << (source.empty() ? "standard output" : source);
-        return false;
-      }
-      gzfile.Write(strm);
-      if (!gzfile) {
-        LOG(ERROR) << "Compress: Can't write to file: "
-                   << (source.empty() ? "standard output" : source);
-        return false;
-      }
-  } else if (!source.empty()) {
-    std::ofstream strm(source,
-                             std::ios_base::out | std::ios_base::binary);
-    if (!strm) {
+bool Compress(const Fst<Arc> &fst, const std::string &source) {
+  std::ofstream fstrm;
+  if (!source.empty()) {
+    fstrm.open(source, std::ios_base::out | std::ios_base::binary);
+    if (!fstrm) {
       LOG(ERROR) << "Compress: Can't open file: " << source;
       return false;
     }
-    Compress(fst, strm);
-  } else {
-    Compress(fst, std::cout);
   }
-  return true;
+  std::ostream &ostrm = fstrm.is_open() ? fstrm : std::cout;
+  Compress(fst, ostrm);
+  return !!ostrm;
 }
 
 template <class Arc>
@@ -808,32 +767,18 @@ bool Decompress(std::istream &strm, const std::string &source,
 
 // Returns true on success.
 template <class Arc>
-bool Decompress(const std::string &source, MutableFst<Arc> *fst,
-                const bool gzip = false) {
-  if (gzip) {
-    IGzFile gzfile(source);
-    if (!gzfile) {
-      LOG(ERROR) << "Decompress: Can't open file: "
-                 << (source.empty() ? "standard input" : source);
-      return false;
-    }
-    Decompress(*gzfile.Read(), source, fst);
-    if (!gzfile) {
-      LOG(ERROR) << "Decompress: Can't read from file: "
-                 << (source.empty() ? "standard input" : source);
-      return false;
-    }
-  } else if (!source.empty()) {
-    std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
-    if (!strm) {
+bool Decompress(const std::string &source, MutableFst<Arc> *fst) {
+  std::ifstream fstrm;
+  if (!source.empty()) {
+    fstrm.open(source, std::ios_base::in | std::ios_base::binary);
+    if (!fstrm) {
       LOG(ERROR) << "Decompress: Can't open file: " << source;
       return false;
     }
-    Decompress(strm, source, fst);
-  } else {
-    Decompress(std::cin, "standard input", fst);
   }
-  return true;
+  std::istream &istrm = fstrm.is_open() ? fstrm : std::cin;
+  Decompress(istrm, source.empty() ? "standard input" : source, fst);
+  return !!istrm;
 }
 
 }  // namespace fst
index e015a11..c12e690 100644 (file)
@@ -14,8 +14,7 @@
 namespace fst {
 namespace script {
 
-using CompressInnerArgs =
-    std::tuple<const FstClass &, const std::string &, const bool>;
+using CompressInnerArgs = std::tuple<const FstClass &, const std::string &>;
 
 using CompressArgs = WithReturnValue<bool, CompressInnerArgs>;
 
@@ -23,14 +22,12 @@ template <class Arc>
 void Compress(CompressArgs *args) {
   const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
   const auto &source = std::get<1>(args->args);
-  const auto gzip = std::get<2>(args->args);
-  args->retval = Compress(fst, source, gzip);
+  args->retval = Compress(fst, source);
 }
 
-bool Compress(const FstClass &fst, const std::string &source, const bool gzip);
+bool Compress(const FstClass &fst, const std::string &source);
 
-using DecompressInnerArgs =
-    std::tuple<const std::string &, MutableFstClass *, const bool>;
+using DecompressInnerArgs = std::tuple<const std::string &, MutableFstClass *>;
 
 using DecompressArgs = WithReturnValue<bool, DecompressInnerArgs>;
 
@@ -38,12 +35,10 @@ template <class Arc>
 void Decompress(DecompressArgs *args) {
   const auto &source = std::get<0>(args->args);
   MutableFst<Arc> *fst = std::get<1>(args->args)->GetMutableFst<Arc>();
-  const auto gzip = std::get<2>(args->args);
-  args->retval = Decompress(source, fst, gzip);
+  args->retval = Decompress(source, fst);
 }
 
-bool Decompress(const std::string &source, MutableFstClass *fst,
-                const bool gzip);
+bool Decompress(const std::string &source, MutableFstClass *fst);
 
 }  // namespace script
 }  // namespace fst
diff --git a/src/include/fst/extensions/compress/gzfile.h b/src/include/fst/extensions/compress/gzfile.h
deleted file mode 100644 (file)
index a02cdc2..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// See www.openfst.org for extensive documentation on this weighted
-// finite-state transducer library.
-//
-// Resource handles for gzip files written to or read from stringstreams. These
-// are necessary to provide the compression routines with streams reading from
-// or writing to compressed files (or the UNIX standard streams), and are not
-// intended for general use.
-
-#ifndef FST_EXTENSIONS_COMPRESS_GZFILE_H_
-#define FST_EXTENSIONS_COMPRESS_GZFILE_H_
-
-#include <cstddef>
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include <fst/compat.h>
-#include <fst/log.h>
-#include <fst/fst.h>
-#include <zlib.h>
-
-namespace fst {
-
-// Gives the zlib gzFile type an OO-like interface. String inputs are all
-// C-style strings. The caller is responsible to get the file modes appropriate
-// for the IO methods being called. The ! operator can be used to check for
-// errors after construction or read/writing.
-class GzFile {
- public:
-  GzFile(const char *source, const char *mode)
-      : gzfile_(gzopen(source, mode)), error_(gzfile_ == nullptr) {}
-
-  ~GzFile() { gzclose(gzfile_); }
-
-  bool operator!() const { return error_; }
-
-  // Returns false on EOF and sets error if short read does not reach an EOF.
-  int Read(void *buf, unsigned int size) {
-    const auto bytes_read = gzread(gzfile_, buf, size);
-    if ((bytes_read < size) && !gzeof(gzfile_)) error_ = true;
-    return bytes_read;
-  }
-
-  // Sets error on short writes.
-  void Write(const char *buf, unsigned int size) {
-    if (gzwrite(gzfile_, buf, size) != size) error_ = true;
-  }
-
- private:
-  gzFile gzfile_;
-  bool error_;
-};
-
-// Resource handle for writing stringstream to GzFile.
-class OGzFile {
- public:
-  explicit OGzFile(const std::string &source) : OGzFile(source.c_str()) {}
-
-  explicit OGzFile(const char *source) : gz_(GzFile(source, "wb")) {}
-
-  inline bool operator!() const { return !gz_; }
-
-  void Write(const std::stringstream &ssbuf) {
-    const auto sbuf = ssbuf.str();
-    gz_.Write(sbuf.data(), sbuf.size());
-  }
-
- private:
-  GzFile gz_;
-};
-
-// Resource handle for reading stringstream from GzFile.
-class IGzFile {
- public:
-  explicit IGzFile(const std::string &source) : IGzFile(source.c_str()) {}
-
-  explicit IGzFile(const char *source) : gz_(GzFile(source, "rb")) {}
-
-  inline bool operator!() const { return !gz_; }
-
-  // This is a great case for "move", but GCC 4 is missing the C+11 standard
-  // move constructor for stringstream, so a unique_ptr is the next best thing.
-  std::unique_ptr<std::stringstream> Read() {
-    char buf[bufsize_];
-    std::unique_ptr<std::stringstream> sstrm(new std::stringstream);
-    // We always read at least once, and the result of the last read is always
-    // pushed onto the stringstream. We use the "write" member because << onto
-    // a stringstream stops at the null byte, which might be data!
-    int bytes_read;
-    while ((bytes_read = gz_.Read(buf, bufsize_)) == bufsize_) {
-      sstrm->write(buf, bufsize_);
-    }
-    sstrm->write(buf, bytes_read);
-    return sstrm;
-  }
-
- private:
-  GzFile gz_;
-  // This is the same size as the default internal buffer for zlib.
-  static const size_t bufsize_ = 8192;
-};
-
-}  // namespace fst
-
-#endif  // FST_EXTENSIONS_COMPRESS_GZFILE_H_
index b2176ba..a141132 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_EXTENSIONS_FAR_CREATE_H_
 
 #include <libgen.h>
+
 #include <sstream>
 #include <string>
 #include <vector>
index c313d41..a20cc13 100644 (file)
@@ -69,8 +69,9 @@ void FarPrintStrings(const std::vector<std::string> &isources,
       syms.reset(fst->InputSymbols()->Copy());
     std::string str;
     VLOG(2) << "Handling key: " << key;
-    StringPrinter<Arc> string_printer(token_type,
-                                      syms ? syms.get() : fst->InputSymbols());
+    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) {
       if (print_key) std::cout << key << FLAGS_far_field_separator[0];
index a01cec1..f36de7b 100644 (file)
 
 #include <fst/types.h>
 #include <fst/log.h>
-#include <fst/compose.h>  // for ComposeOptions
-#include <fst/util.h>
-
-#include <fst/script/arg-packs.h>
-#include <fst/script/fst-class.h>
-#include <fst/script/shortest-path.h>
-
 #include <fst/extensions/mpdt/compose.h>
 #include <fst/extensions/mpdt/expand.h>
 #include <fst/extensions/mpdt/info.h>
 #include <fst/extensions/mpdt/reverse.h>
-
 #include <fst/extensions/pdt/pdtscript.h>  // For LabelClassPair,
-                                               // FstClassPair, and to detect
-                                               // any collisions.
+#include <fst/compose.h>               // for ComposeOptions
+#include <fst/util.h>
+#include <fst/script/arg-packs.h>
+#include <fst/script/fst-class.h>
+#include <fst/script/shortest-path.h>
+// FstClassPair, and to detect
+// any collisions.
 
 namespace fst {
 namespace script {
index 900d7d3..dec023e 100644 (file)
@@ -41,6 +41,11 @@ class BitmapIndex {
   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);
+  }
+
   bool Get(size_t index) const {
     return (bits_[index >> kStorageLogBitSize] &
             (kOne << (index & kStorageBlockMask))) != 0;
index e2b1475..14fcd76 100644 (file)
@@ -21,7 +21,7 @@ namespace internal {
 template <class Label>
 class PhiFstMatcherData {
  public:
-  PhiFstMatcherData(
+  explicit PhiFstMatcherData(
       Label phi_label = FLAGS_phi_fst_phi_label,
       bool phi_loop = FLAGS_phi_fst_phi_loop,
       MatcherRewriteMode rewrite_mode = RewriteMode(FLAGS_phi_fst_rewrite_mode))
index 2a12cbb..1e54094 100644 (file)
@@ -607,7 +607,209 @@ class Adder<LogWeightTpl<T>> {
     return Sum();
   }
 
-  Weight Sum() { return Weight(sum_); }
+  Weight Sum() const { return Weight(sum_); }
+
+  void Reset(Weight w = Weight::Zero()) {
+    sum_ = w.Value();
+    c_ = 0.0;
+  }
+
+ private:
+  double sum_;
+  double c_;   // Kahan compensation.
+};
+
+// Real semiring: (+, *, 0, 1).
+template <class T>
+class RealWeightTpl : public FloatWeightTpl<T> {
+ public:
+  using typename FloatWeightTpl<T>::ValueType;
+  using FloatWeightTpl<T>::Value;
+  using ReverseWeight = RealWeightTpl;
+  using Limits = FloatLimits<T>;
+
+  RealWeightTpl() noexcept : FloatWeightTpl<T>() {}
+
+  constexpr RealWeightTpl(T f) : FloatWeightTpl<T>(f) {}
+
+  static constexpr RealWeightTpl Zero() { return 0; }
+
+  static constexpr RealWeightTpl One() { return 1; }
+
+  static constexpr RealWeightTpl NoWeight() { return Limits::NumberBad(); }
+
+  static const std::string &Type() {
+    static const std::string *const type = new std::string(
+        std::string("real") + FloatWeightTpl<T>::GetPrecisionString());
+    return *type;
+  }
+
+  constexpr bool Member() const {
+    // The comments for TropicalWeightTpl<>::Member() apply here unchanged.
+    return Limits::NegInfinity() < Value();
+  }
+
+  RealWeightTpl<T> Quantize(float delta = kDelta) const {
+    if (!Member() || Value() == Limits::PosInfinity()) {
+      return *this;
+    } else {
+      return RealWeightTpl<T>(std::floor(Value() / delta + 0.5F) * delta);
+    }
+  }
+
+  constexpr RealWeightTpl<T> Reverse() const { return *this; }
+
+  static constexpr uint64 Properties() {
+    return kLeftSemiring | kRightSemiring | kCommutative;
+  }
+};
+
+// Single-precision log weight.
+using RealWeight = RealWeightTpl<float>;
+
+// Double-precision log weight.
+using Real64Weight = RealWeightTpl<double>;
+
+namespace internal {
+
+// a + b = KahanRealSum(a, b, ...).
+// Kahan compensated summation provides an error bound that is
+// independent of the number of addends. c is the compensation.
+inline double KahanRealSum(double a, double b, double *c) {
+  double y = b - *c;
+  double t = a + y;
+  *c = (t - a) - y;
+  return t;
+}
+
+};  // namespace internal
+
+// The comments for Times(Tropical...) above apply here unchanged.
+template <class T>
+inline RealWeightTpl<T> Plus(const RealWeightTpl<T> &w1,
+                             const RealWeightTpl<T> &w2) {
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  return RealWeightTpl<T>(f1 + f2);
+}
+
+inline RealWeightTpl<float> Plus(const RealWeightTpl<float> &w1,
+                                 const RealWeightTpl<float> &w2) {
+  return Plus<float>(w1, w2);
+}
+
+inline RealWeightTpl<double> Plus(const RealWeightTpl<double> &w1,
+                                  const RealWeightTpl<double> &w2) {
+  return Plus<double>(w1, w2);
+}
+
+template <class T>
+inline RealWeightTpl<T> Minus(const RealWeightTpl<T> &w1,
+                             const RealWeightTpl<T> &w2) {
+  // The comments for Divide(Tropical...) above apply here unchanged.
+  const T f1 = w1.Value();
+  const T f2 = w2.Value();
+  return RealWeightTpl<T>(f1 - f2);
+}
+
+inline RealWeightTpl<float> Minus(const RealWeightTpl<float> &w1,
+                                 const RealWeightTpl<float> &w2) {
+  return Minus<float>(w1, w2);
+}
+
+inline RealWeightTpl<double> Minus(const RealWeightTpl<double> &w1,
+                                  const RealWeightTpl<double> &w2) {
+  return Minus<double>(w1, w2);
+}
+
+// The comments for Times(Tropical...) above apply here similarly.
+template <class T>
+constexpr RealWeightTpl<T> Times(const RealWeightTpl<T> &w1,
+                                 const RealWeightTpl<T> &w2) {
+  return RealWeightTpl<T>(w1.Value() * w2.Value());
+}
+
+constexpr RealWeightTpl<float> Times(const RealWeightTpl<float> &w1,
+                                     const RealWeightTpl<float> &w2) {
+  return Times<float>(w1, w2);
+}
+
+constexpr RealWeightTpl<double> Times(const RealWeightTpl<double> &w1,
+                                      const RealWeightTpl<double> &w2) {
+  return Times<double>(w1, w2);
+}
+
+template <class T>
+constexpr RealWeightTpl<T> Divide(const RealWeightTpl<T> &w1,
+                                 const RealWeightTpl<T> &w2,
+                                 DivideType typ = DIVIDE_ANY) {
+  using Weight = RealWeightTpl<T>;
+  return w2.Member() ? Weight(w1.Value() / w2.Value()) : Weight::NoWeight();
+}
+
+constexpr RealWeightTpl<float> Divide(const RealWeightTpl<float> &w1,
+                                      const RealWeightTpl<float> &w2,
+                                      DivideType typ = DIVIDE_ANY) {
+  return Divide<float>(w1, w2, typ);
+}
+
+constexpr RealWeightTpl<double> Divide(const RealWeightTpl<double> &w1,
+                                       const RealWeightTpl<double> &w2,
+                                       DivideType typ = DIVIDE_ANY) {
+  return Divide<double>(w1, w2, typ);
+}
+
+// The comments for Power<>(Tropical...) above apply here unchanged.
+
+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));
+}
+
+// Specializes the library-wide template to use the above implementation; rules
+// of function template instantiation require this be a full instantiation.
+
+template <>
+constexpr RealWeightTpl<float> Power<RealWeightTpl<float>>(
+    const RealWeightTpl<float> &weight, size_t n) {
+  return Power<float, size_t, true>(weight, n);
+}
+
+template <>
+constexpr RealWeightTpl<double> Power<RealWeightTpl<double>>(
+    const RealWeightTpl<double> &weight, size_t n) {
+  return Power<double, size_t, true>(weight, n);
+}
+
+// Specialization using the Kahan compensated summation.
+template <class T>
+class Adder<RealWeightTpl<T>> {
+ public:
+  using Weight = RealWeightTpl<T>;
+
+  explicit Adder(Weight w = Weight::Zero())
+      : sum_(w.Value()),
+        c_(0.0) { }
+
+  Weight Add(const Weight &w) {
+    using Limits = FloatLimits<T>;
+    const T f = w.Value();
+    if (f == Limits::PosInfinity()) {
+      sum_ = f;
+    } else if (sum_ == Limits::PosInfinity()) {
+      return sum_;
+    } else {
+      sum_ = internal::KahanRealSum(sum_, f, &c_);
+    }
+    return Sum();
+  }
+
+  Weight Sum() const { return Weight(sum_); }
 
   void Reset(Weight w = Weight::Zero()) {
     sum_ = w.Value();
@@ -747,6 +949,20 @@ struct WeightConvert<TropicalWeight, LogWeight> {
 };
 
 template <>
+struct WeightConvert<RealWeight, LogWeight> {
+  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());
+  }
+};
+
+template <>
 struct WeightConvert<Log64Weight, LogWeight> {
   constexpr LogWeight operator()(const Log64Weight &w) const {
     return w.Value();
@@ -762,12 +978,71 @@ struct WeightConvert<TropicalWeight, Log64Weight> {
 };
 
 template <>
+struct WeightConvert<RealWeight, Log64Weight> {
+  Log64Weight operator()(const RealWeight &w) const {
+    return -log(w.Value());
+  }
+};
+
+template <>
+struct WeightConvert<Real64Weight, Log64Weight> {
+  Log64Weight operator()(const Real64Weight &w) const {
+    return -log(w.Value());
+  }
+};
+
+template <>
 struct WeightConvert<LogWeight, Log64Weight> {
   constexpr Log64Weight operator()(const LogWeight &w) const {
     return w.Value();
   }
 };
 
+// Converts to real.
+template <>
+struct WeightConvert<LogWeight, RealWeight> {
+  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());
+  }
+};
+
+template <>
+struct WeightConvert<Real64Weight, RealWeight> {
+  constexpr RealWeight operator()(const Real64Weight &w) const {
+    return w.Value();
+  }
+};
+
+// Converts to real64
+template <>
+struct WeightConvert<LogWeight, Real64Weight> {
+  Real64Weight operator()(const LogWeight &w) const {
+    return exp(-w.Value());
+  }
+};
+
+template <>
+struct WeightConvert<Log64Weight, Real64Weight> {
+  Real64Weight operator()(const Log64Weight &w) const {
+    return exp(-w.Value());
+  }
+};
+
+template <>
+struct WeightConvert<RealWeight, Real64Weight> {
+  constexpr Real64Weight operator()(const RealWeight &w) const {
+    return w.Value();
+  }
+};
+
+
 // This function object returns random integers chosen from [0,
 // num_random_weights). The boolean 'allow_zero' determines whether Zero() and
 // zero divisors should be returned in the random weight generation. This is
@@ -821,6 +1096,20 @@ class WeightGenerate<LogWeightTpl<T>>
   Weight operator()() const { return Weight(Generate::operator()()); }
 };
 
+template <class T>
+class WeightGenerate<RealWeightTpl<T>>
+    : public FloatWeightGenerate<RealWeightTpl<T>> {
+ public:
+  using Weight = RealWeightTpl<T>;
+  using Generate = FloatWeightGenerate<Weight>;
+
+  explicit WeightGenerate(bool allow_zero = true,
+                          size_t num_random_weights = kNumRandomWeights)
+      : Generate(allow_zero, num_random_weights) {}
+
+  Weight operator()() const { return Weight(Generate::operator()()); }
+};
+
 // This function object returns random integers chosen from [0,
 // num_random_weights). The boolean 'allow_zero' determines whether Zero() and
 // zero divisors should be returned in the random weight generation. This is
index 0400626..14f8994 100644 (file)
@@ -54,16 +54,15 @@ using LogArc = ArcTpl<LogWeight>;
 // Stores.
 
 template <class Element, class U>
-class DefaultCompactStore;
+class CompactArcStore;
 
 template <class Arc>
 class DefaultCacheStore;
 
 // Compactors.
 
-template <class AC, class U,
-          class S = DefaultCompactStore<typename AC::Element, U>>
-class DefaultCompactor;
+template <class AC, class U, class S = CompactArcStore<typename AC::Element, U>>
+class CompactArcCompactor;
 
 // FST templates.
 
@@ -73,10 +72,10 @@ class CompactFst;
 // The Unsigned type is used to represent indices into the compact arc array.
 template <class Arc, class ArcCompactor, class Unsigned = uint32,
           class CompactStore =
-              DefaultCompactStore<typename ArcCompactor::Element, Unsigned>,
+              CompactArcStore<typename ArcCompactor::Element, Unsigned>,
           class CacheStore = DefaultCacheStore<Arc>>
 using CompactArcFst =
-    CompactFst<Arc, DefaultCompactor<ArcCompactor, Unsigned, CompactStore>,
+    CompactFst<Arc, CompactArcCompactor<ArcCompactor, Unsigned, CompactStore>,
                CacheStore>;
 
 template <class Arc, class U = uint32>
index df55c90..d59aad6 100644 (file)
@@ -415,7 +415,7 @@ class StateIterator {
   StateId s_;
 };
 
-// Flags to control the behavior on an arc iterator.
+// Flags to control the behavior on an arc iterator via SetFlags().
 // Value() gives valid ilabel.
 static constexpr uint8 kArcILabelValue = 0x01;
 // Value() call gives valid olabel.
@@ -451,9 +451,9 @@ class ArcIteratorBase {
   virtual void Reset() = 0;
   // Advances to arbitrary arc by position.
   virtual void Seek(size_t) = 0;
-  // Returns current behavorial flags.
+  // Returns current behavorial flags, a bitmask of kArcFlags.
   virtual uint8 Flags() const = 0;
-  // Sets behavorial flags.
+  // Sets behavorial flags, a bitmask of kArcFlags.
   virtual void SetFlags(uint8, uint8) = 0;
 };
 
index c917806..7a8770f 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef FST_LABEL_REACHABLE_H_
 #define FST_LABEL_REACHABLE_H_
 
-#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -21,6 +20,7 @@
 #include <fst/util.h>
 #include <fst/vector-fst.h>
 
+#include <unordered_map>
 
 namespace fst {
 
@@ -86,12 +86,12 @@ class LabelReachableData {
  private:
   LabelReachableData() {}
 
-  bool reach_input_;                              // Input labels considered?
-  bool keep_relabel_data_;                        // Save label2index_ to file?
-  bool have_relabel_data_;                        // Using label2index_?
-  Label final_label_;                             // Final label.
+  bool reach_input_;                               // Input labels considered?
+  bool keep_relabel_data_;                         // Save label2index_ to file?
+  bool have_relabel_data_;                         // Using label2index_?
+  Label final_label_;                              // Final label.
   std::unordered_map<Label, Label> label2index_;  // Finds index for a label.
-  std::vector<LabelIntervalSet> interval_sets_;   // Interval sets per state.
+  std::vector<LabelIntervalSet> interval_sets_;    // Interval sets per state.
 };
 
 // Apply a new state order to a vector of LabelIntervalSets. order[i] gives
index 52c5bfd..c2aa62c 100644 (file)
@@ -21,7 +21,6 @@
 #include <fst/label-reachable.h>
 #include <fst/matcher.h>
 
-
 DECLARE_string(save_relabel_ipairs);
 DECLARE_string(save_relabel_opairs);
 
@@ -416,11 +415,15 @@ template <class M,
           uint32 flags = kLookAheadEpsilons | kLookAheadWeight |
                          kLookAheadPrefix | kLookAheadNonEpsilonPrefix |
                          kLookAheadKeepRelabelData,
-          class Accumulator = DefaultAccumulator<typename M::Arc>,
-          class Reachable = LabelReachable<typename M::Arc, Accumulator>>
+          class Accum = DefaultAccumulator<typename M::Arc>,
+          class R = LabelReachable<typename M::Arc, Accum>>
 class LabelLookAheadMatcher
     : public LookAheadMatcherBase<typename M::FST::Arc> {
  public:
+  using Matcher = M;
+  using Accumulator = Accum;
+  using Reachable = R;
+
   using FST = typename M::FST;
   using Arc = typename FST::Arc;
   using Label = typename Arc::Label;
@@ -551,7 +554,7 @@ class LabelLookAheadMatcher
 
   template <class LFST>
   void InitLookAheadFst(const LFST &fst, bool copy = false) {
-    lfst_ = static_cast<const Fst<Arc> *>(&fst);
+    lfst_ = &fst;
     if (label_reachable_) {
       const bool reach_input = Type(false) == MATCH_OUTPUT;
       label_reachable_->ReachInit(fst, reach_input, copy);
@@ -582,12 +585,12 @@ class LabelLookAheadMatcher
     const bool reach_input = match_type == MATCH_INPUT;
     if (data) {
       if (reach_input == data->ReachInput()) {
-        label_reachable_.reset(new Reachable(data, accumulator));
+        label_reachable_ = fst::make_unique<Reachable>(data, accumulator);
       }
     } else if ((reach_input && (kFlags & kInputLookAheadMatcher)) ||
                (!reach_input && (kFlags & kOutputLookAheadMatcher))) {
-      label_reachable_.reset(new Reachable(fst, reach_input, accumulator,
-                                           kFlags & kLookAheadKeepRelabelData));
+      label_reachable_ = fst::make_unique<Reachable>(
+          fst, reach_input, accumulator, kFlags & kLookAheadKeepRelabelData);
     }
   }
 
@@ -605,7 +608,7 @@ template <class LFST>
 inline bool LabelLookAheadMatcher<M, flags, Accumulator,
                                   Reachable>::LookAheadFst(const LFST &fst,
                                                            StateId s) {
-  if (static_cast<const Fst<Arc> *>(&fst) != lfst_) InitLookAheadFst(fst);
+  if (&fst != lfst_) InitLookAheadFst(fst);
   ClearLookAheadWeight();
   ClearLookAheadPrefix();
   if (!label_reachable_) return true;
@@ -637,6 +640,34 @@ inline bool LabelLookAheadMatcher<M, flags, Accumulator,
   return reach_arc || reach_final;
 }
 
+// Relabels the fst with Reachable::Reachable.  Relabels input
+// if data.First() is non-null, otherwise relabels output.
+// Optionally saves the input/output label pairs to a file
+// if save_relabel_ipairs/opairs is non-empty.
+template <class Reachable, class FST, class Data>
+void RelabelForReachable(FST *fst, const Data &data,
+                         const std::string &save_relabel_ipairs,
+                         const std::string &save_relabel_opairs) {
+  using Label = typename FST::Arc::Label;
+  if (data.First() != nullptr) {  // reach_input.
+    Reachable reachable(data.SharedFirst());
+    reachable.Relabel(fst, /*relabel_input=*/true);
+    if (!save_relabel_ipairs.empty()) {
+      std::vector<std::pair<Label, Label>> pairs;
+      reachable.RelabelPairs(&pairs, /*avoid_collisions=*/true);
+      WriteLabelPairs(save_relabel_ipairs, pairs);
+    }
+  } else {
+    Reachable reachable(data.SharedSecond());
+    reachable.Relabel(fst, /*relabel_input=*/false);
+    if (!save_relabel_opairs.empty()) {
+      std::vector<std::pair<Label, Label>> pairs;
+      reachable.RelabelPairs(&pairs, /*avoid_collisions=*/true);
+      WriteLabelPairs(save_relabel_opairs, pairs);
+    }
+  }
+}
+
 // Label-lookahead relabeling class.
 template <class Arc, class Data = LabelReachableData<typename Arc::Label>>
 class LabelLookAheadRelabeler {
@@ -687,25 +718,12 @@ inline LabelLookAheadRelabeler<Arc, Data>::LabelLookAheadRelabeler(
     // do a deep copy when the Fst is modified.
     mfst.reset(static_cast<MutableFst<Arc> *>(&fst));
   } else {
-    mfst.reset(new VectorFst<Arc>(fst));
-  }
-  if (data->First()) {  // reach_input.
-    Reachable reachable(data->SharedFirst());
-    reachable.Relabel(mfst.get(), true);
-    if (!FLAGS_save_relabel_ipairs.empty()) {
-      std::vector<std::pair<Label, Label>> pairs;
-      reachable.RelabelPairs(&pairs, true);
-      WriteLabelPairs(FLAGS_save_relabel_ipairs, pairs);
-    }
-  } else {
-    Reachable reachable(data->SharedSecond());
-    reachable.Relabel(mfst.get(), false);
-    if (!FLAGS_save_relabel_opairs.empty()) {
-      std::vector<std::pair<Label, Label>> pairs;
-      reachable.RelabelPairs(&pairs, true);
-      WriteLabelPairs(FLAGS_save_relabel_opairs, pairs);
-    }
+    mfst = fst::make_unique<VectorFst<Arc>>(fst);
   }
+
+  RelabelForReachable<Reachable>(mfst.get(), *data, FLAGS_save_relabel_ipairs,
+                                 FLAGS_save_relabel_opairs);
+
   if (is_mutable) {
     // Pointer was just borrowed, don't delete it.
     mfst.release();
@@ -732,15 +750,16 @@ class LookAheadMatcher {
       : owned_fst_(fst.Copy()),
         base_(owned_fst_->InitMatcher(match_type)),
         lookahead_(false) {
-    if (!base_) base_.reset(new SortedMatcher<FST>(owned_fst_.get(),
-                                                   match_type));
+    if (!base_)
+      base_ =
+          fst::make_unique<SortedMatcher<FST>>(owned_fst_.get(), match_type);
   }
 
   // This doesn't copy the FST.
   LookAheadMatcher(const FST *fst, MatchType match_type)
       : base_(fst->InitMatcher(match_type)),
         lookahead_(false) {
-    if (!base_) base_.reset(new SortedMatcher<FST>(fst, match_type));
+    if (!base_) base_ = fst::make_unique<SortedMatcher<FST>>(fst, match_type);
   }
 
   // This makes a copy of the FST.
index 3f095e9..3d63bd4 100644 (file)
@@ -86,12 +86,20 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
 
   MatcherFst() : ImplToExpandedFst<Impl>(std::make_shared<Impl>(FST(), Name)) {}
 
+  // Constructs a MatcherFst from an FST, which is the underlying FST type used
+  // by this class. Uses the existing Data if present, and runs Init on it.
+  // Stores fst internally, making a thread-safe copy of it.
   explicit MatcherFst(const FST &fst, std::shared_ptr<Data> data = nullptr)
       : ImplToExpandedFst<Impl>(data ? CreateImpl(fst, Name, data)
                                      : CreateDataAndImpl(fst, Name)) {}
 
-  explicit MatcherFst(const Fst<Arc> &fst)
-      : ImplToExpandedFst<Impl>(CreateDataAndImpl(fst, Name)) {}
+  // Constructs a MatcherFst from an Fst<Arc>, which is *not* the underlying
+  // FST type used by this class. Uses the existing Data if present, and
+  // runs Init on it.  Stores fst internally, converting Fst<Arc> to FST and
+  // therefore making a deep copy.
+  explicit MatcherFst(const Fst<Arc> &fst, std::shared_ptr<Data> data = nullptr)
+      : ImplToExpandedFst<Impl>(data ? CreateImpl(fst, Name, data)
+                                     : CreateDataAndImpl(fst, Name)) {}
 
   // See Fst<>::Copy() for doc.
   MatcherFst(const MatcherFst &fst, bool safe = false)
@@ -157,6 +165,7 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
  protected:
   using ImplToFst<Impl, ExpandedFst<Arc>>::GetImpl;
 
+  // Makes a thread-safe copy of fst.
   static std::shared_ptr<Impl> CreateDataAndImpl(const FST &fst,
                                                  const std::string &name) {
     FstMatcher imatcher(fst, MATCH_INPUT);
@@ -166,12 +175,14 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
                                              omatcher.GetSharedData()));
   }
 
+  // Makes a deep copy of fst.
   static std::shared_ptr<Impl> CreateDataAndImpl(const Fst<Arc> &fst,
                                                  const std::string &name) {
     FST result(fst);
     return CreateDataAndImpl(result, name);
   }
 
+  // Makes a thread-safe copy of fst.
   static std::shared_ptr<Impl> CreateImpl(const FST &fst,
                                           const std::string &name,
                                           std::shared_ptr<Data> data) {
@@ -181,6 +192,16 @@ class MatcherFst : public ImplToExpandedFst<internal::AddOnImpl<F, Data>> {
     return impl;
   }
 
+  // Makes a deep copy of fst.
+  static std::shared_ptr<Impl> CreateImpl(const Fst<Arc> &fst,
+                                          const std::string &name,
+                                          std::shared_ptr<Data> data) {
+    auto impl = std::make_shared<Impl>(fst, name);
+    impl->SetAddOn(data);
+    Init init(&impl);
+    return impl;
+  }
+
   explicit MatcherFst(std::shared_ptr<Impl> impl)
       : ImplToExpandedFst<Impl>(impl) {}
 
index 2b80c68..b0eef87 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <fst/mutable-fst.h>  // for all internal FST accessors.
 
-
 namespace fst {
 
 // Matchers find and iterate through requested labels at FST states. In the
@@ -531,7 +530,7 @@ void HashMatcher<FST>::SetState(typename FST::Arc::StateId s) {
   // Resets everything for the state.
   state_ = s;
   loop_.nextstate = state_;
-  aiter_.reset(new ArcIterator<FST>(fst_, state_));
+  aiter_ = fst::make_unique<ArcIterator<FST>>(fst_, state_);
   if (match_type_ == MATCH_NONE) {
     FSTERROR() << "HashMatcher: Bad match type";
     error_ = true;
@@ -1521,14 +1520,15 @@ class Matcher {
   Matcher(const FST &fst, MatchType match_type)
       : owned_fst_(fst.Copy()),
         base_(owned_fst_->InitMatcher(match_type)) {
-    if (!base_) base_.reset(new SortedMatcher<FST>(owned_fst_.get(),
-                                                   match_type));
+    if (!base_)
+      base_ =
+          fst::make_unique<SortedMatcher<FST>>(owned_fst_.get(), match_type);
   }
 
   // This doesn't copy the FST.
   Matcher(const FST *fst, MatchType match_type)
       : base_(fst->InitMatcher(match_type)) {
-    if (!base_) base_.reset(new SortedMatcher<FST>(fst, match_type));
+    if (!base_) base_ = fst::make_unique<SortedMatcher<FST>>(fst, match_type);
   }
 
   // This makes a copy of the FST.
index c4d7d25..b1a9766 100644 (file)
@@ -30,7 +30,6 @@
 #include <fst/shortest-distance.h>
 #include <fst/state-map.h>
 
-
 namespace fst {
 namespace internal {
 
@@ -225,7 +224,7 @@ class CyclicMinimizer {
     PrePartition(fst);
     // Allocates arc iterator queue.
     ArcIterCompare comp(P_);
-    aiter_queue_.reset(new ArcIterQueue(comp));
+    aiter_queue_ = fst::make_unique<ArcIterQueue>(comp);
   }
   // Partitions all classes with destination C.
   void Split(ClassId C) {
index 79fef33..329a927 100644 (file)
@@ -89,6 +89,37 @@ inline ProductWeight<W1, W2> Divide(const ProductWeight<W1, W2> &w1,
                                Divide(w1.Value2(), w2.Value2(), typ));
 }
 
+// Specialization for product weight
+template <class W1, class W2>
+class Adder<ProductWeight<W1, W2>> {
+ public:
+  using Weight = ProductWeight<W1, W2>;
+
+  Adder() {}
+
+  explicit Adder(Weight w)
+      : adder1_(w.Value1()),
+        adder2_(w.Value2()) {}
+
+  Weight Add(const Weight &w) {
+    adder1_.Add(w.Value1());
+    adder2_.Add(w.Value2());
+    return Sum();
+  }
+
+  Weight Sum() const { return Weight(adder1_.Sum(), adder2_.Sum()); }
+
+  void Reset(Weight w = Weight::Zero()) {
+    adder1_.Reset(w.Value1());
+    adder2_.Reset(w.Value2());
+  }
+
+ private:
+  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.
index a50332a..ad80e13 100644 (file)
@@ -119,10 +119,8 @@ void Push(const Fst<Arc> &ifst, MutableFst<Arc> *ofst, uint8 ptype,
     if (ptype & kPushWeights) {
       ShortestDistance(gfst, &gdistance, rtype == REWEIGHT_TO_INITIAL, delta);
     } else {
-      ArcMapFst<Arc, Arc, RmWeightMapper<Arc>> uwfst(ifst,
-                                                      RmWeightMapper<Arc>());
-      ArcMapFst<Arc, GallicArc<Arc, gtype>, ToGallicMapper<Arc, gtype>> guwfst(
-          uwfst, ToGallicMapper<Arc, gtype>());
+      auto uwfst = MakeArcMapFst(ifst, RmWeightMapper<Arc>());
+      auto guwfst = MakeArcMapFst(uwfst, ToGallicMapper<Arc, gtype>());
       ShortestDistance(guwfst, &gdistance, rtype == REWEIGHT_TO_INITIAL, delta);
     }
     auto total_weight = GallicWeight::One();
index ecadc1a..4326965 100644 (file)
@@ -22,7 +22,6 @@
 #include <fst/topsort.h>
 #include <fst/weight.h>
 
-
 namespace fst {
 
 // The Queue interface is:
@@ -110,7 +109,7 @@ class TrivialQueue : public QueueBase<S> {
 
   TrivialQueue() : QueueBase<StateId>(TRIVIAL_QUEUE), front_(kNoStateId) {}
 
-  virtual ~TrivialQueue() = default;
+  ~TrivialQueue() override = default;
 
   StateId Head() const final { return front_; }
 
@@ -138,7 +137,7 @@ class FifoQueue : public QueueBase<S> {
 
   FifoQueue() : QueueBase<StateId>(FIFO_QUEUE) {}
 
-  virtual ~FifoQueue() = default;
+  ~FifoQueue() override = default;
 
   StateId Head() const override { return queue_.front(); }
 
@@ -164,7 +163,7 @@ class LifoQueue : public QueueBase<S> {
 
   LifoQueue() : QueueBase<StateId>(LIFO_QUEUE) {}
 
-  virtual ~LifoQueue() = default;
+  ~LifoQueue() override = default;
 
   StateId Head() const final { return stack_.top(); }
 
@@ -196,7 +195,7 @@ class ShortestFirstQueue : public QueueBase<S> {
   explicit ShortestFirstQueue(Compare comp)
       : QueueBase<StateId>(SHORTEST_FIRST_QUEUE), heap_(comp) {}
 
-  virtual ~ShortestFirstQueue() = default;
+  ~ShortestFirstQueue() override = default;
 
   StateId Head() const override { return heap_.Top(); }
 
@@ -279,7 +278,7 @@ class NaturalShortestFirstQueue
   explicit NaturalShortestFirstQueue(const std::vector<Weight> &distance)
       : ShortestFirstQueue<StateId, Compare>(Compare(distance, less_)) {}
 
-  virtual ~NaturalShortestFirstQueue() = default;
+  ~NaturalShortestFirstQueue() override = default;
 
  private:
   // This is non-static because the constructor for non-idempotent weights will
@@ -420,7 +419,7 @@ class TopOrderQueue : public QueueBase<S> {
         order_(order),
         state_(order.size(), kNoStateId) {}
 
-  virtual ~TopOrderQueue() = default;
+  ~TopOrderQueue() override = default;
 
   StateId Head() const final { return state_[front_]; }
 
@@ -467,7 +466,7 @@ class StateOrderQueue : public QueueBase<S> {
   StateOrderQueue()
       : QueueBase<StateId>(STATE_ORDER_QUEUE), front_(0), back_(kNoStateId) {}
 
-  virtual ~StateOrderQueue() = default;
+  ~StateOrderQueue() override = default;
 
   StateId Head() const final { return front_; }
 
@@ -522,7 +521,7 @@ class SccQueue : public QueueBase<S> {
         front_(0),
         back_(kNoStateId) {}
 
-  virtual ~SccQueue() = default;
+  ~SccQueue() override = default;
 
   StateId Head() const final {
     while ((front_ <= back_) &&
@@ -624,13 +623,13 @@ class AutoQueue : public QueueBase<S> {
     const auto props =
         fst.Properties(kAcyclic | kCyclic | kTopSorted | kUnweighted, false);
     if ((props & kTopSorted) || fst.Start() == kNoStateId) {
-      queue_.reset(new StateOrderQueue<StateId>());
+      queue_ = fst::make_unique<StateOrderQueue<StateId>>();
       VLOG(2) << "AutoQueue: using state-order discipline";
     } else if (props & kAcyclic) {
-      queue_.reset(new TopOrderQueue<StateId>(fst, filter));
+      queue_ = fst::make_unique<TopOrderQueue<StateId>>(fst, filter);
       VLOG(2) << "AutoQueue: using top-order discipline";
     } else if ((props & kUnweighted) && (Weight::Properties() & kIdempotent)) {
-      queue_.reset(new LifoQueue<StateId>());
+      queue_ = fst::make_unique<LifoQueue<StateId>>();
       VLOG(2) << "AutoQueue: using LIFO discipline";
     } else {
       uint64 properties;
@@ -642,8 +641,8 @@ class AutoQueue : public QueueBase<S> {
       std::unique_ptr<Less> less;
       std::unique_ptr<Compare> comp;
       if (distance && (Weight::Properties() & kPath) == kPath) {
-        less.reset(new Less);
-        comp.reset(new Compare(*distance, *less));
+        less = fst::make_unique<Less>();
+        comp = fst::make_unique<Compare>(*distance, *less);
       }
       // Finds the queue type to use per SCC.
       bool unweighted;
@@ -652,14 +651,14 @@ class AutoQueue : public QueueBase<S> {
                    &unweighted);
       // If unweighted and semiring is idempotent, uses LIFO queue.
       if (unweighted) {
-        queue_.reset(new LifoQueue<StateId>());
+        queue_ = fst::make_unique<LifoQueue<StateId>>();
         VLOG(2) << "AutoQueue: using LIFO discipline";
         return;
       }
       // If all the SCC are trivial, the FST is acyclic and the scc number gives
       // the topological order.
       if (all_trivial) {
-        queue_.reset(new TopOrderQueue<StateId>(scc_));
+        queue_ = fst::make_unique<TopOrderQueue<StateId>>(scc_);
         VLOG(2) << "AutoQueue: using top-order discipline";
         return;
       }
@@ -678,21 +677,22 @@ class AutoQueue : public QueueBase<S> {
                     << ": using shortest-first discipline";
             break;
           case LIFO_QUEUE:
-            queues_[i].reset(new LifoQueue<StateId>());
+            queues_[i] = fst::make_unique<LifoQueue<StateId>>();
             VLOG(3) << "AutoQueue: SCC #" << i << ": using LIFO discipline";
             break;
           case FIFO_QUEUE:
           default:
-            queues_[i].reset(new FifoQueue<StateId>());
+            queues_[i] = fst::make_unique<FifoQueue<StateId>>();
             VLOG(3) << "AutoQueue: SCC #" << i << ": using FIFO discipine";
             break;
         }
       }
-      queue_.reset(new SccQueue<StateId, QueueBase<StateId>>(scc_, &queues_));
+      queue_ = fst::make_unique<SccQueue<StateId, QueueBase<StateId>>>(
+          scc_, &queues_);
     }
   }
 
-  virtual ~AutoQueue() = default;
+  ~AutoQueue() override = default;
 
   StateId Head() const final { return queue_->Head(); }
 
@@ -836,7 +836,7 @@ class NaturalAStarQueue : public ShortestFirstQueue<
       : ShortestFirstQueue<StateId, Compare>(
             Compare(distance, less_, estimate)) {}
 
-  ~NaturalAStarQueue() = default;
+  ~NaturalAStarQueue() override = default;
 
  private:
   // This is non-static because the constructor for non-idempotent weights will
@@ -875,7 +875,7 @@ class PruneQueue : public QueueBase<typename Queue::StateId> {
         class_fnc_(class_fnc),
         threshold_(std::move(threshold)) {}
 
-  virtual ~PruneQueue() = default;
+  ~PruneQueue() override = default;
 
   StateId Head() const override { return queue_->Head(); }
 
@@ -929,7 +929,7 @@ class NaturalPruneQueue final
       : PruneQueue<Queue, NaturalLess<Weight>, ClassFnc>(
             distance, queue, NaturalLess<Weight>(), class_fnc, threshold) {}
 
-  virtual ~NaturalPruneQueue() = default;
+  ~NaturalPruneQueue() override = default;
 };
 
 // Filter-based pruning queue discipline: enqueues a state only if allowed by
@@ -944,7 +944,7 @@ class FilterQueue : public QueueBase<typename Queue::StateId> {
   FilterQueue(Queue *queue, const Filter &filter)
       : QueueBase<StateId>(OTHER_QUEUE), queue_(queue), filter_(filter) {}
 
-  virtual ~FilterQueue() = default;
+  ~FilterQueue() override = default;
 
   StateId Head() const final { return queue_->Head(); }
 
index c9106db..c9497bf 100644 (file)
@@ -305,10 +305,10 @@ class ArcSampler<Arc, FastLogProbArcSelector<Arc>> {
         selector_(sampler.selector_),
         max_length_(sampler.max_length_) {
     if (fst) {
-      accumulator_.reset(new Accumulator());
+      accumulator_ = fst::make_unique<Accumulator>();
       accumulator_->Init(*fst);
     } else {  // Shallow copy.
-      accumulator_.reset(new Accumulator(*sampler.accumulator_));
+      accumulator_ = fst::make_unique<Accumulator>(*sampler.accumulator_);
     }
   }
 
index f7d018c..e86371f 100644 (file)
@@ -17,7 +17,6 @@
 #include <fst/replace.h>
 #include <fst/test-properties.h>
 
-
 namespace fst {
 
 using RationalFstOptions = CacheOptions;
@@ -227,7 +226,8 @@ class RationalFstImpl : public FstImpl<A> {
   ReplaceFst<Arc> *Replace() const {
     if (!replace_) {
       fst_tuples_[0].second = rfst_.Copy();
-      replace_.reset(new ReplaceFst<Arc>(fst_tuples_, replace_options_));
+      replace_ =
+          fst::make_unique<ReplaceFst<Arc>>(fst_tuples_, replace_options_);
     }
     return replace_.get();
   }
index 844b550..50c2a3a 100644 (file)
@@ -99,11 +99,10 @@ void Relabel(MutableFst<Arc> *fst, const SymbolTable *old_isymbols,
       }
     }
 
-    for (SymbolTableIterator siter(*old_isymbols); !siter.Done();
-         siter.Next()) {
-      const auto old_index = siter.Value();
-      const auto symbol = siter.Symbol();
-      auto new_index = new_isymbols->Find(siter.Symbol());
+    for (const auto &sitem : *old_isymbols) {
+      const auto old_index = sitem.Label();
+      const auto symbol = sitem.Symbol();
+      auto new_index = new_isymbols->Find(symbol);
       if (new_index == kNoLabel) {
         if (unknown_ilabel != kNoLabel) {
           new_index = unknown_ilabel;
@@ -134,11 +133,10 @@ void Relabel(MutableFst<Arc> *fst, const SymbolTable *old_isymbols,
         ++num_missing_syms;
       }
     }
-    for (SymbolTableIterator siter(*old_osymbols); !siter.Done();
-         siter.Next()) {
-      const auto old_index = siter.Value();
-      const auto symbol = siter.Symbol();
-      auto new_index = new_osymbols->Find(siter.Symbol());
+    for (const auto &sitem : *old_osymbols) {
+      const auto old_index = sitem.Label();
+      const auto symbol = sitem.Symbol();
+      auto new_index = new_osymbols->Find(symbol);
       if (new_index == kNoLabel) {
         if (unknown_olabel != kNoLabel) {
           new_index = unknown_olabel;
@@ -252,18 +250,16 @@ class RelabelFstImpl : public CacheImpl<Arc> {
     SetOutputSymbols(old_osymbols);
     if (old_isymbols && new_isymbols &&
         old_isymbols->LabeledCheckSum() != new_isymbols->LabeledCheckSum()) {
-      for (SymbolTableIterator siter(*old_isymbols); !siter.Done();
-           siter.Next()) {
-        input_map_[siter.Value()] = new_isymbols->Find(siter.Symbol());
+      for (const auto &sitem : *old_isymbols) {
+        input_map_[sitem.Label()] = new_isymbols->Find(sitem.Symbol());
       }
       SetInputSymbols(new_isymbols);
       relabel_input_ = true;
     }
     if (old_osymbols && new_osymbols &&
         old_osymbols->LabeledCheckSum() != new_osymbols->LabeledCheckSum()) {
-      for (SymbolTableIterator siter(*old_osymbols); !siter.Done();
-           siter.Next()) {
-        output_map_[siter.Value()] = new_osymbols->Find(siter.Symbol());
+      for (const auto &sitem : *old_osymbols) {
+        output_map_[sitem.Label()] = new_osymbols->Find(sitem.Symbol());
       }
       SetOutputSymbols(new_osymbols);
       relabel_output_ = true;
index 3bf7910..401ad52 100644 (file)
@@ -225,9 +225,9 @@ class VectorHashReplaceStateTable {
       }
     }
     state_table_.reset(
-        new StateTable(new ReplaceRootSelector<StateId, PrefixId>,
-                       new ReplaceFstStateFingerprint<StateId, PrefixId>,
-                       new ReplaceFingerprint<StateId, PrefixId>(&size_array_),
+        new StateTable(ReplaceRootSelector<StateId, PrefixId>(),
+                       ReplaceFstStateFingerprint<StateId, PrefixId>(),
+                       ReplaceFingerprint<StateId, PrefixId>(&size_array_),
                        root_size_, root_size_ + size_array_.back()));
   }
 
@@ -237,9 +237,9 @@ class VectorHashReplaceStateTable {
         size_array_(table.size_array_),
         prefix_table_(table.prefix_table_) {
     state_table_.reset(
-        new StateTable(new ReplaceRootSelector<StateId, PrefixId>,
-                       new ReplaceFstStateFingerprint<StateId, PrefixId>,
-                       new ReplaceFingerprint<StateId, PrefixId>(&size_array_),
+        new StateTable(ReplaceRootSelector<StateId, PrefixId>(),
+                       ReplaceFstStateFingerprint<StateId, PrefixId>(),
+                       ReplaceFingerprint<StateId, PrefixId>(&size_array_),
                        root_size_, root_size_ + size_array_.back()));
   }
 
index 18646b4..92d45a3 100644 (file)
@@ -68,9 +68,9 @@ class FstClassImplBase : public FstClassBase {
   virtual int64 NumStates() const = 0;
   virtual bool ReserveArcs(int64, size_t) = 0;
   virtual void ReserveStates(int64) = 0;
-  virtual void SetInputSymbols(SymbolTable *) = 0;
+  virtual void SetInputSymbols(const SymbolTable *) = 0;
   virtual bool SetFinal(int64, const WeightClass &) = 0;
-  virtual void SetOutputSymbols(SymbolTable *) = 0;
+  virtual void SetOutputSymbols(const SymbolTable *) = 0;
   virtual void SetProperties(uint64, uint64) = 0;
   virtual bool SetStart(int64) = 0;
   ~FstClassImplBase() override {}
@@ -212,7 +212,7 @@ class FstClassImpl : public FstClassImplBase {
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
-  void SetInputSymbols(SymbolTable *isyms) final {
+  void SetInputSymbols(const SymbolTable *isyms) final {
     static_cast<MutableFst<Arc> *>(impl_.get())->SetInputSymbols(isyms);
   }
 
@@ -225,7 +225,7 @@ class FstClassImpl : public FstClassImplBase {
   }
 
   // Warning: calling this method casts the FST to a mutable FST.
-  void SetOutputSymbols(SymbolTable *osyms) final {
+  void SetOutputSymbols(const SymbolTable *osyms) final {
     static_cast<MutableFst<Arc> *>(impl_.get())->SetOutputSymbols(osyms);
   }
 
@@ -451,7 +451,7 @@ class MutableFstClass : public FstClass {
 
   static MutableFstClass *Read(const std::string &source, bool convert = false);
 
-  void SetInputSymbols(SymbolTable *isyms) {
+  void SetInputSymbols(const SymbolTable *isyms) {
     GetImpl()->SetInputSymbols(isyms);
   }
 
@@ -460,7 +460,7 @@ class MutableFstClass : public FstClass {
     return GetImpl()->SetFinal(s, weight);
   }
 
-  void SetOutputSymbols(SymbolTable *osyms) {
+  void SetOutputSymbols(const SymbolTable *osyms) {
     GetImpl()->SetOutputSymbols(osyms);
   }
 
index b1c5b26..0037402 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <fst/arcfilter.h>
 #include <fst/cache.h>
+#include <fst/equal.h>
 #include <fst/queue.h>
 #include <fst/reverse.h>
 #include <fst/test-properties.h>
@@ -61,7 +62,8 @@ namespace internal {
 // conventions, fst may not be freed before this class. Vector distance
 // should not be modified by the user between these calls. The Error() method
 // returns true iff an error was encountered.
-template <class Arc, class Queue, class ArcFilter>
+template <class Arc, class Queue, class ArcFilter,
+          class WeightEqual = WeightApproxEqual>
 class ShortestDistanceState {
  public:
   using StateId = typename Arc::StateId;
@@ -74,7 +76,7 @@ class ShortestDistanceState {
         distance_(distance),
         state_queue_(opts.state_queue),
         arc_filter_(opts.arc_filter),
-        delta_(opts.delta),
+        weight_equal_(opts.delta),
         first_path_(opts.first_path),
         retain_(retain),
         source_id_(0),
@@ -115,7 +117,7 @@ class ShortestDistanceState {
   std::vector<Weight> *distance_;
   Queue *state_queue_;
   ArcFilter arc_filter_;
-  const float delta_;
+  WeightEqual weight_equal_;           // Determines when relaxation stops.
   const bool first_path_;
   const bool retain_;  // Retain and reuse information across calls.
 
@@ -130,9 +132,9 @@ class ShortestDistanceState {
 
 // Compute the shortest distance; if source is kNoStateId, uses the initial
 // state of the FST.
-template <class Arc, class Queue, class ArcFilter>
-void ShortestDistanceState<Arc, Queue, ArcFilter>::ShortestDistance(
-    StateId source) {
+template <class Arc, class Queue, class ArcFilter, class WeightEqual>
+    void ShortestDistanceState<Arc, Queue, ArcFilter,
+                               WeightEqual>::ShortestDistance(StateId source) {
   if (fst_.Start() == kNoStateId) {
     if (fst_.Properties(kError, false)) error_ = true;
     return;
@@ -195,7 +197,7 @@ void ShortestDistanceState<Arc, Queue, ArcFilter>::ShortestDistance(
       auto &na = adder_[nextstate];
       auto &nr = radder_[nextstate];
       auto weight = Times(r, arc.weight);
-      if (!ApproxEqual(nd, Plus(nd, weight), delta_)) {
+      if (!weight_equal_(nd, Plus(nd, weight))) {
         nd = na.Add(weight);
         nr.Add(weight);
         if (!nd.Member() || !nr.Sum().Member()) {
index c34a756..debf8bf 100644 (file)
@@ -271,7 +271,7 @@ class Adder<SignedLogWeightTpl<T>> {
     return Sum();
   }
 
-  Weight Sum() { return Weight(X1(ssum_ ? 1.0 : -1.0), X2(sum_)); }
+  Weight Sum() const { return Weight(X1(ssum_ ? 1.0 : -1.0), X2(sum_)); }
 
   void Reset(Weight w = Weight::Zero()) {
     ssum_ = w.IsPositive();
@@ -348,6 +348,40 @@ struct WeightConvert<SignedLog64Weight, Log64Weight> {
   }
 };
 
+// Converts to real.
+template <>
+struct WeightConvert<SignedLogWeight, RealWeight> {
+  RealWeight operator()(const SignedLogWeight &weight) const {
+    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()));
+  }
+};
+
+// Converts to real64.
+template <>
+struct WeightConvert<SignedLogWeight, Real64Weight> {
+  Real64Weight operator()(const SignedLogWeight &weight) const {
+    return Real64Weight(weight.Value1().Value() *
+                        exp(-weight.Value2().Value()));
+  }
+};
+
+template <>
+struct WeightConvert<SignedLog64Weight, Real64Weight> {
+  Real64Weight operator()(const SignedLog64Weight &weight) const {
+    return Real64Weight(weight.Value1().Value() *
+                        exp(-weight.Value2().Value()));
+  }
+};
+
 // Converts to signed log.
 template <>
 struct WeightConvert<TropicalWeight, SignedLogWeight> {
@@ -371,6 +405,22 @@ struct WeightConvert<Log64Weight, SignedLogWeight> {
 };
 
 template <>
+struct WeightConvert<RealWeight, SignedLogWeight> {
+  SignedLogWeight operator()(const RealWeight &weight) const {
+    return SignedLogWeight(weight.Value() >= 0 ? 1.0 : -1.0,
+                           -log(std::abs(weight.Value())));
+  }
+};
+
+template <>
+struct WeightConvert<Real64Weight, SignedLogWeight> {
+  SignedLogWeight operator()(const Real64Weight &weight) const {
+    return SignedLogWeight(weight.Value() >= 0 ? 1.0 : -1.0,
+                           -log(std::abs(weight.Value())));
+  }
+};
+
+template <>
 struct WeightConvert<SignedLog64Weight, SignedLogWeight> {
   SignedLogWeight operator()(const SignedLog64Weight &weight) const {
     return SignedLogWeight(weight.Value1(), weight.Value2().Value());
@@ -400,6 +450,22 @@ struct WeightConvert<Log64Weight, SignedLog64Weight> {
 };
 
 template <>
+struct WeightConvert<RealWeight, SignedLog64Weight> {
+  SignedLog64Weight operator()(const RealWeight &weight) const {
+    return SignedLog64Weight(weight.Value() >= 0 ? 1.0 : -1.0,
+                             -log(std::abs(weight.Value())));
+  }
+};
+
+template <>
+struct WeightConvert<Real64Weight, SignedLog64Weight> {
+  SignedLog64Weight operator()(const Real64Weight &weight) const {
+    return SignedLog64Weight(weight.Value() >= 0 ? 1.0 : -1.0,
+                             -log(std::abs(weight.Value())));
+  }
+};
+
+template <>
 struct WeightConvert<SignedLogWeight, SignedLog64Weight> {
   SignedLog64Weight operator()(const SignedLogWeight &weight) const {
     return SignedLog64Weight(weight.Value1(), weight.Value2().Value());
index 3bdadde..a00d1e1 100644 (file)
@@ -19,7 +19,6 @@
 #include <fst/cache.h>
 #include <fst/mutable-fst.h>
 
-
 namespace fst {
 
 // StateMapper Interface. The class determines how states are mapped; useful for
@@ -407,7 +406,7 @@ class IdentityStateMapper {
   Weight Final(StateId state) const { return fst_.Final(state); }
 
   void SetState(StateId state) {
-    aiter_.reset(new ArcIterator<Fst<Arc>>(fst_, state));
+    aiter_ = fst::make_unique<ArcIterator<Fst<Arc>>>(fst_, state);
   }
 
   bool Done() const { return aiter_->Done(); }
index d7523ad..2777b3d 100644 (file)
@@ -119,7 +119,7 @@ class VectorStateTable : public VectorBiTable<typename T::StateId, T, FP> {
   using VectorBiTable<StateId, StateTuple, FP>::Size;
   using VectorBiTable<StateId, StateTuple, FP>::Fingerprint;
 
-  explicit VectorStateTable(FP *fingerprint = nullptr, size_t table_size = 0)
+  explicit VectorStateTable(const FP &fingerprint = FP(), size_t table_size = 0)
       : VectorBiTable<StateId, StateTuple, FP>(fingerprint, table_size) {}
 
   StateId FindState(const StateTuple &tuple) { return FindId(tuple); }
@@ -146,8 +146,9 @@ class VectorHashStateTable
   using VectorHashBiTable<StateId, StateTuple, Select, FP, H>::Fingerprint;
   using VectorHashBiTable<StateId, StateTuple, Select, FP, H>::Hash;
 
-  VectorHashStateTable(Select *select, FP *fingerprint, H *hash,
-                       size_t vector_size = 0, size_t tuple_size = 0)
+  VectorHashStateTable(const Select &select, const FP &fingerprint,
+                       const H &hash, size_t vector_size = 0,
+                       size_t tuple_size = 0)
       : VectorHashBiTable<StateId, StateTuple, Select, FP, H>(
             select, fingerprint, hash, vector_size, tuple_size) {}
 
@@ -340,7 +341,7 @@ class ComposeFingerprint {
   ComposeFingerprint(StateId nstates1, StateId nstates2)
       : mult1_(nstates1), mult2_(nstates1 * nstates2) {}
 
-  size_t operator()(const StateTuple &tuple) {
+  size_t operator()(const StateTuple &tuple) const {
     return tuple.StateId1() + tuple.StateId2() * mult1_ +
            tuple.GetFilterState().Hash() * mult2_;
   }
@@ -378,13 +379,13 @@ class ProductComposeStateTable
 
   ProductComposeStateTable(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
                            size_t table_size = 0)
-      : StateTable(new ComposeFingerprint<StateTuple>(CountStates(fst1),
-                                                      CountStates(fst2)),
+      : StateTable(ComposeFingerprint<StateTuple>(CountStates(fst1),
+                                                  CountStates(fst2)),
                    table_size) {}
 
   ProductComposeStateTable(
       const ProductComposeStateTable<Arc, StateTuple> &table)
-      : StateTable(new ComposeFingerprint<StateTuple>(table.Fingerprint())) {}
+      : StateTable(ComposeFingerprint<StateTuple>(table.Fingerprint())) {}
 
   constexpr bool Error() const { return false; }
 
index 3fb137f..25facc9 100644 (file)
@@ -29,6 +29,8 @@ namespace fst {
 
 enum StringTokenType { SYMBOL = 1, BYTE = 2, UTF8 = 3 };
 
+enum EpsilonSymbolPrintType { NONEPS_SYMBOLS = 1, SYMBOLS_INCL_EPS = 2 };
+
 namespace internal {
 
 template <class Label>
@@ -89,13 +91,21 @@ 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.
 template <class Label>
 bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
                           const SymbolTable &syms,
-                          const std::string &sep = FLAGS_fst_field_separator) {
+                          const std::string &sep = FLAGS_fst_field_separator,
+                          EpsilonSymbolPrintType eps_sym_print_type =
+                              EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
   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;
     ostrm << delim;
     const std::string &symbol = syms.Find(label);
     if (symbol.empty()) {
@@ -112,12 +122,20 @@ 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.
 template <class Label>
 bool LabelsToNumericString(const std::vector<Label> &labels, std::string *str,
-                           const std::string &sep = FLAGS_fst_field_separator) {
+                           const std::string &sep = FLAGS_fst_field_separator,
+                           EpsilonSymbolPrintType eps_sym_print_type =
+                               EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
   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;
     ostrm << delim;
     ostrm << label;
     delim = std::string(1, sep.back());
@@ -136,7 +154,7 @@ class StringCompiler {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  explicit StringCompiler(StringTokenType token_type,
+  explicit StringCompiler(StringTokenType token_type = BYTE,
                           const SymbolTable *syms = nullptr,
                           Label unknown_label = kNoLabel,
                           bool allow_negative = false)
@@ -224,6 +242,9 @@ class StringCompiler {
   StringCompiler &operator=(const StringCompiler &) = delete;
 };
 
+// A useful alias when using StdArc.
+using StdStringCompiler = StringCompiler<StdArc>;
+
 // Helpers for StringPrinter.
 
 // Converts an FST to a vector of output labels. To get input labels, use
@@ -261,13 +282,17 @@ 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.
-// Returns true on success.
+// 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.
 template <class Label>
 bool LabelsToString(const std::vector<Label> &labels, std::string *str,
                     StringTokenType ttype = BYTE,
                     const SymbolTable *syms = nullptr,
-                    const std::string &sep = FLAGS_fst_field_separator) {
+                    const std::string &sep = FLAGS_fst_field_separator,
+                    EpsilonSymbolPrintType eps_sym_print_type =
+                        EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
   switch (ttype) {
     case StringTokenType::BYTE: {
       return LabelsToByteString(labels, str);
@@ -276,9 +301,10 @@ bool LabelsToString(const std::vector<Label> &labels, std::string *str,
       return LabelsToUTF8String(labels, str);
     }
     case StringTokenType::SYMBOL: {
-      return syms ?
-          internal::LabelsToSymbolString(labels, str, *syms, sep) :
-          internal::LabelsToNumericString(labels, str, sep);
+      return syms ? internal::LabelsToSymbolString(labels, str, *syms, sep,
+                                                   eps_sym_print_type)
+                  : internal::LabelsToNumericString(labels, str, sep,
+                                                    eps_sym_print_type);
     }
   }
   return false;
@@ -290,9 +316,13 @@ class StringPrinter {
  public:
   using Label = typename Arc::Label;
 
-  explicit StringPrinter(StringTokenType token_type,
-                         const SymbolTable *syms = nullptr)
-      : token_type_(token_type), syms_(syms) {}
+  explicit StringPrinter(StringTokenType token_type = 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) {}
 
   // 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.
@@ -300,17 +330,24 @@ class StringPrinter {
                   const std::string &sep = FLAGS_fst_field_separator) const {
     std::vector<Label> labels;
     return (StringFstToOutputLabels(fst, &labels) &&
-            LabelsToString(labels, str, token_type_, syms_, sep));
+            LabelsToString(labels, str, token_type_, syms_, sep,
+                           eps_sym_print_type_));
   }
 
  private:
   const StringTokenType token_type_;
   const SymbolTable *syms_;
+  const EpsilonSymbolPrintType
+      eps_sym_print_type_;  // Whether to print epsilons in
+                            // StringTokenType::SYMBOL mode.
 
   StringPrinter(const StringPrinter &) = delete;
   StringPrinter &operator=(const StringPrinter &) = delete;
 };
 
+// A useful alias when using StdArc.
+using StdStringPrinter = StringPrinter<StdArc>;
+
 }  // namespace fst
 
 #endif  // FST_STRING_H_
index 5c965a3..34296fb 100644 (file)
@@ -31,9 +31,9 @@ SymbolTable *PruneSymbolTable(const Fst<Arc> &fst, const SymbolTable &syms,
     }
   }
   auto *pruned = new SymbolTable(syms.Name() + "_pruned");
-  for (SymbolTableIterator stiter(syms); !stiter.Done(); stiter.Next()) {
-    const auto label = stiter.Value();
-    if (seen.count(label)) pruned->AddSymbol(stiter.Symbol(), label);
+  for (const auto &stitem : syms) {
+    const auto label = stitem.Label();
+    if (seen.count(label)) pruned->AddSymbol(stitem.Symbol(), label);
   }
   return pruned;
 }
index 13e3a4f..a0eef84 100644 (file)
@@ -292,8 +292,6 @@ class SymbolTableImpl final : public MutableSymbolTableImpl {
 
 }  // namespace internal
 
-class SymbolTableIterator;
-
 // Symbol (string) to integer (and reverse) mapping.
 //
 // The SymbolTable implements the mappings of labels to strings and reverse.
@@ -307,7 +305,70 @@ class SymbolTableIterator;
 class SymbolTable {
  public:
   using SymbolType = internal::SymbolTableImpl::SymbolType;
-  using iterator = SymbolTableIterator;
+
+  class iterator {
+   public:
+    // TODO(wolfsonkin): Expand `SymbolTable::iterator` to be a random access
+    // iterator.
+    using iterator_category = std::input_iterator_tag;
+
+    class value_type {
+     public:
+      // Return the label of the current symbol.
+      int64 Label() const { return key_; }
+
+      // Return the string of the current symbol.
+      // TODO(wolfsonkin): Consider adding caching.
+      std::string Symbol() const { return table_->Find(key_); }
+
+     private:
+      explicit value_type(const SymbolTable &table, ssize_t pos)
+          : table_(&table), key_(table.GetNthKey(pos)) {}
+
+      // Sets this item to the pos'th element in the symbol table
+      void SetPosition(ssize_t pos) { key_ = table_->GetNthKey(pos); }
+
+      friend class SymbolTable::iterator;
+
+      const SymbolTable *table_;  // Does not own the underlying SymbolTable.
+      int64 key_;
+    };
+
+    using difference_type = std::ptrdiff_t;
+    using pointer = const value_type *const;
+    using reference = const value_type &;
+
+    iterator &operator++() {
+      ++pos_;
+      if (pos_ < nsymbols_) iter_item_.SetPosition(pos_);
+      return *this;
+    }
+
+    iterator operator++(int) {
+      iterator retval = *this;
+      ++(*this);
+      return retval;
+    }
+
+    bool operator==(const iterator &that) const { return (pos_ == that.pos_); }
+
+    bool operator!=(const iterator &that) const { return !(*this == that); }
+
+    reference operator*() { return iter_item_; }
+
+    pointer operator->() const { return &iter_item_; }
+
+   private:
+    explicit iterator(const SymbolTable &table, ssize_t pos = 0)
+        : pos_(pos), nsymbols_(table.NumSymbols()), iter_item_(table, pos) {}
+
+    friend class SymbolTable;
+
+    ssize_t pos_;
+    size_t nsymbols_;
+    value_type iter_item_;
+  };
+
   using const_iterator = iterator;
 
   // Constructs symbol table with an optional name.
@@ -440,10 +501,13 @@ class SymbolTable {
   // Dumps a text representation of the symbol table.
   bool WriteText(const std::string &source) const;
 
-  const_iterator begin() const;
-  const_iterator end() const;
-  const_iterator cbegin() const;
-  const_iterator cend() const;
+  const_iterator begin() const { return const_iterator(*this, 0); }
+
+  const_iterator end() const { return const_iterator(*this, NumSymbols()); }
+
+  const_iterator cbegin() const { return begin(); }
+
+  const_iterator cend() const { return end(); }
 
  protected:
   explicit SymbolTable(std::shared_ptr<internal::SymbolTableImplBase> impl)
@@ -471,98 +535,35 @@ class SymbolTable {
   std::shared_ptr<internal::SymbolTableImplBase> impl_;
 };
 
-namespace internal {
-
-// TODO(wolfsonkin): Consider adding std::tie and structured bindings support.
-class SymbolTableIteratorItem {
- public:
-  explicit SymbolTableIteratorItem(const SymbolTable &table, ssize_t pos)
-      : table_(table), key_(table.GetNthKey(pos)) {}
-
-  // Return the label of the current symbol.
-  int64 Label() const { return key_; }
-
-  // Return the string of the current symbol.
-  // TODO(wolfsonkin): Consider adding caching
-  std::string Symbol() const { return table_.Find(key_); }
-
- private:
-  // Sets this item to the pos'th element in the symbol table
-  void SetPosition(ssize_t pos) { key_ = table_.GetNthKey(pos); }
-
-  friend class fst::SymbolTableIterator;
-  const SymbolTable &table_;
-  int64 key_;
-};
-
-}  // namespace internal
-
 // Iterator class for symbols in a symbol table.
-class SymbolTableIterator {
+class OPENFST_DEPRECATED(
+    "Use SymbolTable::iterator, a C++ compliant iterator, instead")
+    SymbolTableIterator {
  public:
-  using iterator_category = std::input_iterator_tag;
-  using value_type = internal::SymbolTableIteratorItem;
-  using difference_type = std::ptrdiff_t;
-  using pointer = const value_type *const;
-  using reference = const value_type &;
-
   explicit SymbolTableIterator(const SymbolTable &table)
-      : SymbolTableIterator(table, 0) {}
+      : table_(table), iter_(table.begin()), end_(table.end()) {}
 
   ~SymbolTableIterator() {}
 
   // Returns whether iterator is done.
-  bool Done() const { return (pos_ == nsymbols_); }
+  bool Done() const { return (iter_ == end_); }
 
   // Return the key of the current symbol.
-  int64 Value() const { return iter_item_.Label(); }
+  int64 Value() const { return iter_->Label(); }
 
   // Return the string of the current symbol.
-  std::string Symbol() const { return iter_item_.Symbol(); }
+  std::string Symbol() const { return iter_->Symbol(); }
 
   // Advances iterator.
-  void Next() {
-    ++pos_;
-    if (pos_ < nsymbols_) iter_item_.SetPosition(pos_);
-  }
-
-  SymbolTableIterator &operator++() {
-    Next();
-    return *this;
-  }
-
-  SymbolTableIterator operator++(int) {
-    SymbolTableIterator retval = *this;
-    ++(*this);
-    return retval;
-  }
-
-  bool operator==(const SymbolTableIterator &other) const {
-    return (pos_ == other.pos_);
-  }
-
-  bool operator!=(const SymbolTableIterator &other) const {
-    return !(*this == other);
-  }
-
-  reference operator*() { return iter_item_; }
-
-  pointer operator->() const { return &iter_item_; }
+  void Next() { ++iter_; }
 
   // Resets iterator.
-  void Reset() {
-    pos_ = 0;
-    iter_item_.SetPosition(pos_);
-  }
+  void Reset() { iter_ = table_.begin(); }
 
  private:
-  explicit SymbolTableIterator(const SymbolTable &table, ssize_t pos)
-      : pos_(pos), nsymbols_(table.NumSymbols()), iter_item_(table, pos) {}
-  friend class SymbolTable;
-
-  ssize_t pos_;
-  size_t nsymbols_;
-  value_type iter_item_;
+  const SymbolTable &table_;
+  SymbolTable::iterator iter_;
+  const SymbolTable::iterator end_;
 };
 
 // Relabels a symbol table as specified by the input vector of pairs
index eafcb10..8d9c678 100644 (file)
@@ -15,7 +15,6 @@
 #include <fst/connect.h>
 #include <fst/dfs-visit.h>
 
-
 DECLARE_bool(fst_verify_properties);
 
 namespace fst {
@@ -114,10 +113,10 @@ uint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known,
       Arc prev_arc;
       // Creates these only if we need to.
       if (mask & (kIDeterministic | kNonIDeterministic)) {
-        ilabels.reset(new std::unordered_set<Label>());
+        ilabels = fst::make_unique<std::unordered_set<Label>>();
       }
       if (mask & (kODeterministic | kNonODeterministic)) {
-        olabels.reset(new std::unordered_set<Label>());
+        olabels = fst::make_unique<std::unordered_set<Label>>();
       }
       bool first_arc = true;
       for (ArcIterator<Fst<Arc>> aiter(fst, s); !aiter.Done(); aiter.Next()) {
index 9d36677..e585551 100644 (file)
@@ -439,10 +439,8 @@ class WeightedTester {
 
     {
       VLOG(1) << "Check gallic mappers (delayed).";
-      ToGallicMapper<Arc> to_mapper;
-      FromGallicMapper<Arc> from_mapper;
-      ArcMapFst<Arc, GallicArc<Arc>, ToGallicMapper<Arc>> G(T, to_mapper);
-      ArcMapFst<GallicArc<Arc>, Arc, FromGallicMapper<Arc>> F(G, from_mapper);
+      auto G = MakeArcMapFst(T, ToGallicMapper<Arc>());
+      auto F = MakeArcMapFst(G, FromGallicMapper<Arc>());
       CHECK(Equiv(T, F));
     }
   }
@@ -960,8 +958,7 @@ class WeightedTester {
     CHECK(Verify(pfst));
 
     DifferenceFst<Arc> D(fst, DeterminizeFst<Arc>(RmEpsilonFst<Arc>(
-                                  ArcMapFst<Arc, Arc, RmWeightMapper<Arc>>(
-                                      pfst, RmWeightMapper<Arc>()))));
+                                  MakeArcMapFst(pfst, RmWeightMapper<Arc>()))));
     Weight sum1 = Times(ShortestDistance(fst), threshold);
     Weight sum2 = ShortestDistance(D);
     return ApproxEqual(Plus(sum1, sum2), sum1, kTestDelta);
index cae3e15..e261423 100644 (file)
@@ -14,7 +14,6 @@
 #include <fst/fst.h>
 #include <fst/statesort.h>
 
-
 namespace fst {
 
 // DFS visitor class to return topological ordering.
@@ -30,7 +29,7 @@ class TopOrderVisitor {
       : order_(order), acyclic_(acyclic) {}
 
   void InitVisit(const Fst<Arc> &fst) {
-    finish_.reset(new std::vector<StateId>());
+    finish_ = fst::make_unique<std::vector<StateId>>();
     *acyclic_ = true;
   }
 
index 1562581..9e3c541 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 17:0:0
+libfst_la_LDFLAGS = -version-info 19:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index 38a101e..ae10d1a 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 17:0:0
+libfst_la_LDFLAGS = -version-info 19:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index c32c234..9702b84 100644 (file)
@@ -48,6 +48,7 @@ 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;
   }
   strm.seekg(pos);
@@ -63,7 +64,8 @@ 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;
+      LOG(ERROR) << "FstHeader::Read: Bad FST header: " << source
+          << ". Magic number not matched. Got: " << magic_number;
       if (rewind) strm.seekg(pos);
       return false;
   }
index c602aad..942e92b 100644 (file)
@@ -19,13 +19,13 @@ SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
   bool left_has_all = true;
   bool right_has_all = true;
   bool relabel = false;
-  for (SymbolTableIterator liter(left); !liter.Done(); liter.Next()) {
-    merged->AddSymbol(liter.Symbol(), liter.Value());
+  for (const auto &litem : left) {
+    merged->AddSymbol(litem.Symbol(), litem.Label());
     if (right_has_all) {
-      int64 key = right.Find(liter.Symbol());
+      int64 key = right.Find(litem.Symbol());
       if (key == -1) {
         right_has_all = false;
-      } else if (!relabel && key != liter.Value()) {
+      } else if (!relabel && key != litem.Label()) {
         relabel = true;
       }
     }
@@ -36,22 +36,22 @@ SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
   }
   // Adds all symbols we can from right symbol table.
   std::vector<std::string> conflicts;
-  for (SymbolTableIterator riter(right); !riter.Done(); riter.Next()) {
-    int64 key = merged->Find(riter.Symbol());
+  for (const auto &ritem : right) {
+    int64 key = merged->Find(ritem.Symbol());
     if (key != -1) {
       // Symbol already exists, maybe with different value.
-      if (key != riter.Value()) relabel = true;
+      if (key != ritem.Label()) relabel = true;
       continue;
     }
     // Symbol doesn't exist from left.
     left_has_all = false;
-    if (!merged->Find(riter.Value()).empty()) {
+    if (!merged->Find(ritem.Label()).empty()) {
       // We can't add this where we want to, add it later, in order.
-      conflicts.push_back(riter.Symbol());
+      conflicts.push_back(ritem.Symbol());
       continue;
     }
     // There is a hole and we can add this symbol with its ID.
-    merged->AddSymbol(riter.Symbol(), riter.Value());
+    merged->AddSymbol(ritem.Symbol(), ritem.Label());
   }
   if (right_relabel_output) *right_relabel_output = relabel;
   if (left_has_all) return left.Copy();
@@ -62,9 +62,8 @@ SymbolTable *MergeSymbolTable(const SymbolTable &left, const SymbolTable &right,
 
 SymbolTable *CompactSymbolTable(const SymbolTable &syms) {
   std::map<int64, std::string> sorted;
-  SymbolTableIterator stiter(syms);
-  for (; !stiter.Done(); stiter.Next()) {
-    sorted[stiter.Value()] = stiter.Symbol();
+  for (const auto &stitem : syms) {
+    sorted[stitem.Label()] = stitem.Symbol();
   }
   auto *compact = new SymbolTable(syms.Name() + "_compact");
   int64 newkey = 0;
index 48a620f..b7c7b13 100644 (file)
@@ -88,8 +88,8 @@ void DenseSymbolMap::ShrinkToFit() {
 }
 
 void MutableSymbolTableImpl::AddTable(const SymbolTable &table) {
-  for (SymbolTableIterator iter(table); !iter.Done(); iter.Next()) {
-    AddSymbol(iter.Symbol());
+  for (const auto &item : table) {
+    AddSymbol(item.Symbol());
   }
 }
 
@@ -366,13 +366,13 @@ bool SymbolTable::WriteText(std::ostream &strm,
     return false;
   }
   bool once_only = false;
-  for (SymbolTableIterator iter(*this); !iter.Done(); iter.Next()) {
+  for (const auto &item : *this) {
     std::ostringstream line;
-    if (iter.Value() < 0 && !opts.allow_negative_labels && !once_only) {
+    if (item.Label() < 0 && !opts.allow_negative_labels && !once_only) {
       LOG(WARNING) << "Negative symbol table entry when not allowed";
       once_only = true;
     }
-    line << iter.Symbol() << opts.fst_field_separator[0] << iter.Value()
+    line << item.Symbol() << opts.fst_field_separator[0] << item.Label()
          << '\n';
     strm.write(line.str().data(), line.str().length());
   }
@@ -396,18 +396,6 @@ bool SymbolTable::WriteText(const std::string &source) const {
   }
 }
 
-SymbolTable::const_iterator SymbolTable::begin() const {
-  return SymbolTable::const_iterator(*this, 0);
-}
-
-SymbolTable::const_iterator SymbolTable::end() const {
-  return SymbolTable::const_iterator(*this, this->NumSymbols());
-}
-
-SymbolTable::const_iterator SymbolTable::cbegin() const { return begin(); }
-
-SymbolTable::const_iterator SymbolTable::cend() const { return end(); }
-
 bool CompatSymbols(const SymbolTable *syms1, const SymbolTable *syms2,
                    bool warning) {
   // Flag can explicitly override this check.
index 494d40b..f1118ef 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 18:0:0
+libfstscript_la_LDFLAGS = -version-info 19:0:0
 endif
index e7edfe9..a5f5716 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 18:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 19:0:0
 all: all-am
 
 .SUFFIXES:
index dee81c9..adc87d7 100644 (file)
@@ -32,6 +32,8 @@ 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;
@@ -67,6 +69,11 @@ void TestTemplatedWeights(int repeat) {
   WeightTester<LogWeightTpl<T>, LogWeightGenerate> log_tester(log_generate);
   log_tester.Test(repeat);
 
+  using RealWeightGenerate = WeightGenerate<RealWeightTpl<T>>;
+  RealWeightGenerate real_generate;
+  WeightTester<RealWeightTpl<T>, RealWeightGenerate> real_tester(real_generate);
+  real_tester.Test(repeat);
+
   using MinMaxWeightGenerate = WeightGenerate<MinMaxWeightTpl<T>>;
   MinMaxWeightGenerate minmax_generate(true);
   WeightTester<MinMaxWeightTpl<T>, MinMaxWeightGenerate> minmax_tester(
@@ -291,20 +298,24 @@ int main(int argc, char **argv) {
   FLAGS_fst_weight_parentheses = "";
 
   // Makes sure type names for templated weights are consistent.
-  CHECK(TropicalWeight::Type() == "tropical");
+  CHECK_EQ(TropicalWeight::Type(), "tropical");
   CHECK(TropicalWeightTpl<double>::Type() != TropicalWeightTpl<float>::Type());
-  CHECK(LogWeight::Type() == "log");
+  CHECK_EQ(LogWeight::Type(), "log");
   CHECK(LogWeightTpl<double>::Type() != LogWeightTpl<float>::Type());
+  CHECK_EQ(RealWeight::Type(), "real");
+  CHECK(RealWeightTpl<double>::Type() != RealWeightTpl<float>::Type());
   TropicalWeightTpl<double> w(2.0);
   TropicalWeight tw(2.0);
   CHECK_EQ(w.Value(), tw.Value());
 
   TestAdder<TropicalWeight>(1000);
   TestAdder<LogWeight>(1000);
+  TestAdder<RealWeight>(1000);
   TestSignedAdder<SignedLogWeight>(1000);
 
-  TestImplicitConversion<LogWeight>();
   TestImplicitConversion<TropicalWeight>();
+  TestImplicitConversion<LogWeight>();
+  TestImplicitConversion<RealWeight>();
   TestImplicitConversion<MinMaxWeight>();
 
   TestWeightConversion<TropicalWeight, LogWeight>(2.0);