Skip to main content
All 11 Cython extensions are listed here with their architecture patterns, build instructions, performance benchmarks, and troubleshooting steps.

Overview

mySpellChecker uses Cython to compile performance-critical Python code to C++ extensions. The project contains 11 Cython extensions:

Building Extensions

Quick Start

Extensions are automatically built during installation:

Requirements

All Platforms:
  • Python 3.10+
  • Cython 3.0+
  • C++ compiler (gcc 9+, clang 10+, or MSVC 2019+)
macOS (for OpenMP support):
Linux:

Build Outputs

Debug Build

Clean Build

Architecture Patterns

1. Wrapper Pattern (Cython with Fallback)

Some Cython modules have Python wrappers that provide fallback when Cython isn’t available, but not all. There are two patterns in use: Pattern A: Hard import (no fallback) — used by normalize.py:
normalize.py requires the Cython extension to be compiled. It does not provide pure Python fallbacks for core Cython functions. For systems without a C++ compiler, install via a pre-built wheel. Pattern B: try/except with fallback — used by edit_distance.py and syllable_rules.py:
Benefits of Pattern B (where it exists):
  • Modules using this pattern work without Cython compilation
  • Tests run without compilation for those modules
  • Gradual migration path
Important: Since normalize.py (Pattern A) is a core dependency used throughout the library, the package effectively requires Cython extensions to be compiled. Install via pre-built wheels on systems without a C++ compiler.

Checking Active Implementation

2. Declaration Files (.pxd)

.pxd files declare C-level function signatures for cross-module imports:

3. OpenMP Parallel Processing

Only batch_processor.pyx uses OpenMP for parallelization:
Note: OpenMP is optional. If libomp isn’t installed, the library falls back to single-threaded processing.

4. C++ Integration

All extensions use language="c++" for STL containers:

Extension Details

Text Normalization (normalize_c.pyx)

Uses C++ unordered_set for O(1) character lookups with pre-compiled character sets for Myanmar ranges.

Edit Distance (edit_distance_c.pyx)

Row-based DP for O(min(m,n)) space complexity with proper UTF-8 handling for Myanmar’s 3-byte characters.

Syllable Validation (syllable_rules_c.pyx)

22+ validation checks per syllable with pre-computed character sets.

Batch Processor (batch_processor.pyx)

OpenMP parallel for directives for multi-threading with GIL-free C++ processing.

Viterbi POS Tagger (viterbi.pyx)

Log-space computation for numerical stability with optimized backtracking.

Performance Comparison

Benchmark results (10,000 iterations):

Testing Cython Code

Running Tests

Testing Both Implementations

Tests should verify Python/Cython consistency:

Adding New Cython Modules

  1. Create .pyx file:
  2. Create .pxd file (if needed for cross-module imports):
  3. Add to setup.py:
  4. Create Python wrapper:
  5. Add tests and rebuild:

Troubleshooting

”Cannot find Cython” during build

”libomp not found” on macOS

Module import fails after changes

Compiler errors (C++ standard)

Segmentation fault in Cython code

Common causes: releasing GIL while accessing Python objects, buffer overflow in typed memoryviews, use-after-free in C++ containers.

Best Practices

  1. Provide Python fallback where feasible - use Pattern B (try/except) for modules where graceful degradation makes sense. Critical-path modules like normalize use Pattern A (hard imports) where Cython is required for correctness and performance
  2. Use type declarations - fully typed cdef functions for speed
  3. Minimize GIL releases - only release when safe (pure C/C++ operations)
  4. Use memory views for arrays - typed double[:] for efficient array access
  5. Document Cython-specific behavior - note which implementation is active

See Also