Pythonic JavaScript that doesn't suck - a Python-to-JavaScript transpiler with clean syntax and performance
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Python standard library implementations providing familiar APIs for JavaScript environments. RapydScript-NG includes 11 built-in library modules that replicate Python functionality with JavaScript performance.
Mathematical functions and constants following Python's math module API.
# Import in RapydScript source
from math import sin, cos, tan, pi, e
# Mathematical functions
def ceil(x: float) -> int:
"""Return the ceiling of x as an integer."""
def floor(x: float) -> int:
"""Return the floor of x as an integer."""
def trunc(x: float) -> int:
"""Truncate x to an integer."""
def fabs(x: float) -> float:
"""Return the absolute value of x."""
def factorial(n: int) -> int:
"""Return n factorial as an integer."""
def fmod(x: float, y: float) -> float:
"""Return fmod(x, y) as floating point remainder."""
def fsum(iterable) -> float:
"""Return accurate floating point sum of values."""
# Exponential and logarithmic functions
def exp(x: float) -> float:
"""Return e**x (e to the power of x)."""
def log(x: float, base: float = e) -> float:
"""Return the logarithm of x to the given base."""
def pow(x: float, y: float) -> float:
"""Return x**y (x to the power of y)."""
def sqrt(x: float) -> float:
"""Return the square root of x."""
# Trigonometric functions
def sin(x: float) -> float:
def cos(x: float) -> float:
def tan(x: float) -> float:
def asin(x: float) -> float:
def acos(x: float) -> float:
def atan(x: float) -> float:
# Angular conversion
def degrees(x: float) -> float:
"""Convert angle x from radians to degrees."""
def radians(x: float) -> float:
"""Convert angle x from degrees to radians."""
# Hyperbolic functions
def sinh(x: float) -> float:
def cosh(x: float) -> float:
def tanh(x: float) -> float:
# Mathematical constants
pi: float # The mathematical constant π
e: float # The mathematical constant eUsage Examples:
from math import sin, cos, pi, factorial, sqrt
# Trigonometry
angle = pi / 4
print(sin(angle)) # 0.7071067811865476
# Integer operations
print(factorial(5)) # 120
# Square root
print(sqrt(16)) # 4.0Random number generation following Python's random module API.
from random import random, randint, choice, shuffle
def seed(x: int) -> None:
"""Initialize the random number generator."""
def random() -> float:
"""Return a random floating point number in [0.0, 1.0)."""
def randrange(start: int, stop: int = None, step: int = 1) -> int:
"""Return a randomly selected element from range(start, stop, step)."""
def randint(a: int, b: int) -> int:
"""Return a random integer N such that a <= N <= b."""
def uniform(a: float, b: float) -> float:
"""Return a random floating point number N such that a <= N <= b."""
def choice(seq: list) -> any:
"""Return a random element from the non-empty sequence seq."""
def shuffle(seq: list) -> None:
"""Shuffle the sequence x in place."""
def sample(population: list, k: int) -> list:
"""Return a k length list of unique elements chosen from population."""Usage Examples:
from random import randint, choice, shuffle
# Random integer
dice_roll = randint(1, 6)
# Random choice
colors = ['red', 'green', 'blue']
selected = choice(colors)
# Shuffle list in place
deck = list(range(52))
shuffle(deck)Regular expression operations following Python's re module API.
from re import match, search, findall, compile
# Compilation flags
IGNORECASE: int
MULTILINE: int
DOTALL: int
VERBOSE: int
def compile(pattern: str, flags: int = 0) -> RegexObject:
"""Compile a regular expression pattern into a regex object."""
def search(pattern: str, string: str, flags: int = 0) -> MatchObject | None:
"""Scan through string looking for the first location where pattern matches."""
def match(pattern: str, string: str, flags: int = 0) -> MatchObject | None:
"""If zero or more characters at the beginning of string match pattern."""
def split(pattern: str, string: str, maxsplit: int = 0, flags: int = 0) -> list:
"""Split string by the occurrences of pattern."""
def findall(pattern: str, string: str, flags: int = 0) -> list:
"""Return all non-overlapping matches of pattern in string."""
def finditer(pattern: str, string: str, flags: int = 0) -> iterator:
"""Return an iterator over all non-overlapping matches."""
def sub(pattern: str, repl: str, string: str, count: int = 0, flags: int = 0) -> str:
"""Return the string obtained by replacing leftmost non-overlapping occurrences."""
def subn(pattern: str, repl: str, string: str, count: int = 0, flags: int = 0) -> tuple:
"""Perform the same operation as sub(), but return a tuple (new_string, number_of_subs_made)."""
def escape(string: str) -> str:
"""Escape all the characters in pattern except ASCII letters and numbers."""
class MatchObject:
def group(self, *groups) -> str:
"""Return one or more subgroups of the match."""
def groups(self) -> tuple:
"""Return a tuple containing all the subgroups of the match."""
def start(self, group: int = 0) -> int:
"""Return the indices of the start of the substring matched by group."""
def end(self, group: int = 0) -> int:
"""Return the indices of the end of the substring matched by group."""
def span(self, group: int = 0) -> tuple:
"""Return a 2-tuple containing (start(), end()) for group."""
class RegexObject:
def search(self, string: str, pos: int = 0, endpos: int = -1) -> MatchObject | None:
def match(self, string: str, pos: int = 0, endpos: int = -1) -> MatchObject | None:
def split(self, string: str, maxsplit: int = 0) -> list:
def findall(self, string: str, pos: int = 0, endpos: int = -1) -> list:
def sub(self, repl: str, string: str, count: int = 0) -> str:Usage Examples:
import re
# Pattern matching
match = re.search(r'\d+', 'The answer is 42')
if match:
print(match.group()) # '42'
# Find all matches
numbers = re.findall(r'\d+', 'Numbers: 1, 2, 3')
print(numbers) # ['1', '2', '3']
# Substitution
text = re.sub(r'\d+', 'X', 'Replace 123 and 456')
print(text) # 'Replace X and X'Text and binary encoding/decoding utilities.
from encodings import base64encode, base64decode, hexlify, utf8_decode
# Base64 encoding
def base64encode(data: bytes) -> str:
"""Encode binary data using base64."""
def base64decode(data: str) -> bytes:
"""Decode base64 encoded string to binary data."""
def urlsafe_b64encode(data: bytes) -> str:
"""Encode binary data using URL-safe base64."""
def urlsafe_b64decode(data: str) -> bytes:
"""Decode URL-safe base64 encoded string."""
# Hexadecimal encoding
def hexlify(data: bytes) -> str:
"""Return the hexadecimal representation of binary data."""
def unhexlify(hex_string: str) -> bytes:
"""Return the binary data represented by the hexadecimal string."""
# UTF-8 encoding
def utf8_decode(bytes: list) -> str:
"""Decode UTF-8 byte array to string."""
def utf8_encode_js(string: str) -> list:
"""Encode string to UTF-8 as JavaScript array."""
def utf8_encode_native(string: str) -> Uint8Array:
"""Encode string to UTF-8 as native typed array."""Usage Examples:
from encodings import base64encode, base64decode, hexlify
# Base64 encoding
data = b'Hello, World!'
encoded = base64encode(data)
decoded = base64decode(encoded)
# Hex encoding
hex_str = hexlify(b'ABC')
print(hex_str) # '414243'Advanced Encryption Standard implementation with multiple modes.
from aes import AES, generate_key, random_bytes_secure
def generate_key(length: int = 32) -> bytes:
"""Generate a random AES key of specified length."""
def random_bytes_secure(length: int) -> bytes:
"""Generate cryptographically secure random bytes."""
def random_bytes_insecure(length: int) -> bytes:
"""Generate fast pseudo-random bytes (not cryptographically secure)."""
class AES:
def __init__(self, key: bytes):
"""Initialize AES with the given key."""
def encrypt(self, data: bytes, mode: str = 'CBC', iv: bytes = None) -> dict:
"""Encrypt data using specified mode."""
def decrypt(self, encrypted_data: dict) -> bytes:
"""Decrypt data encrypted with encrypt()."""
class CBC:
"""Cipher Block Chaining mode."""
def __init__(self, key: bytes, iv: bytes = None):
def encrypt(self, data: bytes) -> bytes:
def decrypt(self, data: bytes) -> bytes:
class CTR:
"""Counter mode."""
def __init__(self, key: bytes, counter: bytes = None):
def encrypt(self, data: bytes) -> bytes:
def decrypt(self, data: bytes) -> bytes:
class GCM:
"""Galois/Counter Mode (authenticated encryption)."""
def __init__(self, key: bytes, iv: bytes = None):
def encrypt(self, data: bytes, additional_data: bytes = None) -> dict:
def decrypt(self, encrypted_data: dict, additional_data: bytes = None) -> bytes:Usage Examples:
from aes import AES, generate_key, CBC
# Generate key and encrypt data
key = generate_key(32) # 256-bit key
aes = AES(key)
plaintext = b'Secret message'
cbc = CBC(key)
ciphertext = cbc.encrypt(plaintext)
decrypted = cbc.decrypt(ciphertext)Translation and localization support following Python's gettext API.
from gettext import gettext, ngettext, install
def gettext(message: str) -> str:
"""Return the localized translation of message."""
def ngettext(singular: str, plural: str, n: int) -> str:
"""Return the localized translation of message based on count."""
def install(translations: dict) -> None:
"""Install translation catalog for use by gettext functions."""
def register_callback(callback: callable) -> None:
"""Register callback function for translation lookups."""
# Convenience alias
_ = gettext
class Translations:
"""Translation catalog manager."""
def __init__(self, catalog: dict):
def gettext(self, message: str) -> str:
def ngettext(self, singular: str, plural: str, n: int) -> str:Usage Examples:
from gettext import gettext as _, ngettext, install
# Mark strings for translation
title = _('Welcome')
message = _('Hello, World!')
# Plural forms
count = 5
msg = ngettext('Found {} file', 'Found {} files', count).format(count)
# Install translations
translations = {'Hello': 'Hola', 'Welcome': 'Bienvenido'}
install(translations)Universally Unique Identifier generation.
from uuid import uuid4, short_uuid
def uuid4() -> str:
"""Generate a random UUID (version 4) as a string."""
def uuid4_bytes() -> bytes:
"""Generate a random UUID (version 4) as byte array."""
def short_uuid() -> str:
"""Generate a shorter UUID string (base62 encoded)."""
def short_uuid4() -> str:
"""Generate a short random UUID string."""
def decode_short_uuid(short_uuid: str) -> str:
"""Decode short UUID format back to standard UUID."""Usage Examples:
from uuid import uuid4, short_uuid
# Standard UUID
id = uuid4()
print(id) # 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
# Short UUID
short_id = short_uuid()
print(short_id) # 'kHGr7lBX9k2pqE'Stack trace formatting and exception handling utilities.
from traceback import format_exception, print_exc
def format_exception(exc_type: type, exc_value: Exception, exc_traceback: object) -> list:
"""Format exception information as a list of strings."""
def format_exc() -> str:
"""Format the current exception as a string."""
def print_exc(file: object = None) -> None:
"""Print current exception to file (default: stderr)."""
def format_stack(frame: object = None, limit: int = None) -> list:
"""Format current stack trace as a list of strings."""
def print_stack(frame: object = None, limit: int = None, file: object = None) -> None:
"""Print current stack trace to file."""DOM element creation utilities for web development.
from elementmaker import E
def maker_for_document(document: object) -> ElementMaker:
"""Create element maker for specific document object."""
class ElementMaker:
"""Factory for creating DOM elements with Python syntax."""
def __call__(self, tag: str, *children, **attributes) -> Element:
"""Create element with specified tag, children, and attributes."""
def __getattr__(self, tag: str) -> callable:
"""Create element factory for specific tag."""
# Default element maker
E: ElementMakerUsage Examples:
from elementmaker import E
# Create DOM elements
div = E.div(
E.h1('Title', class_='header'),
E.p('Content with ', E.strong('bold'), ' text'),
id='container'
)
# Custom tags
custom = E('custom-element', 'content', data_value='123')Standard operators as functions following Python's operator module.
from operator import add, sub, mul, div, eq, lt
# Arithmetic operators
def add(a, b): return a + b
def sub(a, b): return a - b
def mul(a, b): return a * b
def div(a, b): return a / b
def mod(a, b): return a % b
def pow(a, b): return a ** b
def abs(a): return abs(a)
def neg(a): return -a
# Comparison operators
def eq(a, b): return a == b
def ne(a, b): return a != b
def lt(a, b): return a < b
def le(a, b): return a <= b
def gt(a, b): return a > b
def ge(a, b): return a >= b
# Logical operators
def and_(a, b): return a and b
def or_(a, b): return a or b
def not_(a): return not aUtilities for making JavaScript more Python-like.
from pythonize import strings
def strings(*excluded_methods) -> None:
"""Add Python string methods to JavaScript String prototype.
Args:
*excluded_methods: Method names to exclude from copying
"""Usage Examples:
from pythonize import strings
# Enable Python string methods on JavaScript strings
strings()
# Now JavaScript strings have Python methods
text = "hello world"
print(text.capitalize()) # "Hello world"
print(text.count('l')) # 3
# Exclude specific methods
strings('split', 'replace') # Keep JavaScript versions of thesePython-compatible regular expression operations using JavaScript's RegExp engine with Python syntax.
from re import compile, match, search, findall, finditer, sub, split
# Flag constants
I = IGNORECASE = 2
L = LOCALE = 4
M = MULTILINE = 8
D = DOTALL = 16
U = UNICODE = 32
X = VERBOSE = 64
DEBUG = 128
A = ASCII = 256
def compile(pattern: str, flags: int = 0) -> Pattern:
"""Compile a regular expression pattern into a pattern object."""
def match(pattern: str, string: str, flags: int = 0) -> Match | None:
"""Check for a match only at the beginning of the string."""
def search(pattern: str, string: str, flags: int = 0) -> Match | None:
"""Scan through string looking for the first location where pattern matches."""
def findall(pattern: str, string: str, flags: int = 0) -> list:
"""Return all non-overlapping matches of pattern in string."""
def finditer(pattern: str, string: str, flags: int = 0) -> Iterator:
"""Return an iterator over all non-overlapping matches."""
def sub(pattern: str, repl: str | callable, string: str, count: int = 0, flags: int = 0) -> str:
"""Replace occurrences of pattern in string with repl."""
def subn(pattern: str, repl: str | callable, string: str, count: int = 0, flags: int = 0) -> tuple:
"""Same as sub, but returns tuple (new_string, number_of_subs_made)."""
def split(pattern: str, string: str, maxsplit: int = 0, flags: int = 0) -> list:
"""Split string by occurrences of pattern."""
def escape(pattern: str) -> str:
"""Escape special characters in pattern for literal matching."""
def purge() -> None:
"""Clear the regular expression cache."""
class Pattern:
"""Compiled regular expression pattern."""
pattern: str
flags: int
groups: int
groupindex: dict
def match(self, string: str, pos: int = 0, endpos: int = None) -> Match | None:
"""Match at start of string."""
def search(self, string: str, pos: int = 0, endpos: int = None) -> Match | None:
"""Search for pattern in string."""
def findall(self, string: str, pos: int = 0, endpos: int = None) -> list:
"""Find all matches in string."""
def finditer(self, string: str, pos: int = 0, endpos: int = None) -> Iterator:
"""Return iterator of all matches."""
def sub(self, repl: str | callable, string: str, count: int = 0) -> str:
"""Replace matches with repl."""
def subn(self, repl: str | callable, string: str, count: int = 0) -> tuple:
"""Replace matches with repl, return (result, count)."""
def split(self, string: str, maxsplit: int = 0) -> list:
"""Split string by pattern."""
class Match:
"""Result of a regular expression match."""
string: str
re: Pattern
pos: int
endpos: int
lastindex: int | None
lastgroup: str | None
def group(self, *groups) -> str | tuple:
"""Return one or more subgroups of the match."""
def groups(self, default: str = None) -> tuple:
"""Return tuple of all subgroups."""
def groupdict(self, default: str = None) -> dict:
"""Return dict of named subgroups."""
def start(self, group: int | str = 0) -> int:
"""Return start index of group."""
def end(self, group: int | str = 0) -> int:
"""Return end index of group."""
def span(self, group: int | str = 0) -> tuple:
"""Return (start, end) indices of group."""
def expand(self, template: str) -> str:
"""Expand template using match groups."""Usage Examples:
import re
# Basic pattern matching
pattern = re.compile(r'\d+')
match = pattern.search('Number: 42')
if match:
print(match.group()) # '42'
# Flags usage
text = 'Hello\nWorld'
matches = re.findall(r'hello.*world', text, re.IGNORECASE | re.DOTALL)
# Substitution with groups
def replace_func(match):
return match.group(1).upper()
result = re.sub(r'(\w+)', replace_func, 'hello world')
print(result) # 'HELLO WORLD'
# Named groups
pattern = r'(?P<name>\w+): (?P<value>\d+)'
match = re.search(pattern, 'age: 25')
if match:
print(match.groupdict()) # {'name': 'age', 'value': '25'}
# Split and findall
words = re.split(r'\s+', 'one two three')
numbers = re.findall(r'\d+', 'a1b2c3d')Install with Tessl CLI
npx tessl i tessl/npm-rapydscript-ng