GitHub - nimpylib/nimpylib: "Write Python in Nim!" Python builtins/standard-Lib functions ported to Nim (original) (raw)

NimPylib

C Test JS Test Docs Commits

Write Python in Nim

Nimpylib is a collection of Python-like operators/functions and libraries as well as syntax sugars.


Read Docs|Lib Docs|Wiki about History|Design Wiki

Why NimPyLib?

It helps you to:

Backends

Thanks to Nim supporting multiply backends, pylib currently officially supports to compile to C and JavaScript 1. C++ and ObjC backends are currently not tested.

Demo

import pylib from pylib/Lib/timeit import timeit from pylib/Lib/time import sleep from pylib/Lib/sys import nil # like python's import sys from pylib/Lib/platform import nil # like python's import platform import pylib/Lib/tempfile import pylib/Lib/os

like python's import tempfile; from tempfile import *

more python-stdlib in pylib/Lib/...

from now on, we use > appended # to mean output

print 42 # print can be used with and without parenthesis too, like Python2. #> 42

NOTE: from now on, the following is just valid Python3 code!

only add the following to make it Python:

import platform

from timeit import timeit

from time import sleep

from tempfile import NamedTemporaryFile, TemporaryDirectory

print( f"{9.0} Hello {42} World {1 + 2}" ) # Python-like string interpolation #> 9.0 Hello 42 World 3

class O: @staticmethod def f(): print("O.f")

O.f() #> O.f

def show_range_list(): python_like_range = range(0, -10, -2) print(list(python_like_range)[1:-1]) #> [-2, -4, -6] show_range_list()

Why using so many defs?

as in def, you can write Nim more Python-like

e.g. nondeclared assignment

and all collection literals becomes Python's type

func definition

typing is suppported and optional

def foo(a: int, b = 1, *args) -> int: def add(a, b): return a + b # nesting for i in args: print(i) return add(a, b)

def show_literals(): ls = [1, 2] # if outside def, ls will be an Nim's array,

which is fixed size and "pass by value"

ls_shallow = ls ls.append(3) assert len(ls_shallow) == 3

s = {"Rachel", "Zack"} # if outside def, s will be an Nim's set,

which only supports small ordinal type as elements

s.add("Zack") assert len(s) == 2

d = { # if outside def, d will be an Nim's array[I, (K, V)], # which even lacks __getitem__ method 'a': "kaneki ken" }

assert d['a'].title() == "Kaneki Ken" # if outside def,

all double-quotation marked literals will be Nim's string,

which is more like bytearray

and single-quotation marked literals will be Nim's char,

which repesents a single byte (ASCII character)

show_literals()

python 3.12's type statement

type Number = float | int # which is originally supported by nim-lang itself, however ;)

for i in range(10): print(i, endl=" ") print("done!") #> 0 1 2 3 4 5 6 7 8 9 done!

Python-like variable unpacking

def show_unpack(): data = list(range(3, 15, 2)) (first, second, *_, last) = data assert (first + second + last) == (3 + 5 + 13)

show_unpack()

if (a := 6) > 5: assert a == 6

print(repr("a".center(9))) #> ' a '

print("" or "b") #> b print("a" or "b") #> a

print(not "") #> True

def show_divmod_and_unpack(integer_bytes): (kilo, bite) = divmod(integer_bytes, 1_024) (mega, kilo) = divmod(kilo, 1_024) (giga, mega) = divmod(mega, 1_024) show_divmod_and_unpack(2_313_354_324)

def lambda_closure(arg): anno = lambda: "hello " + arg return anno() assert lambda_closure("world") == "hello world"

if on Linux:

#assert sys.platform == "linux"

if on x86_64:

#platform.machine == "x86_64"

def allAny(): truty = all([True, True, False]) print(truty) #> False

truty = any([True, True, False]) print(truty) #> True allAny()

def a_little_sleep(): "sleep around 0.001 milsecs."

note Nim's os.sleep's unit is milsec,

while Python's time.sleep's is second.

sleep(0.001)

assert timeit(a_little_sleep, number=1000) > 1.0

Support for Python-like with statements

All objects are closed at the end of the with statement

def test_open(): fn = "nimpylib_test_open_some_file.txt" with open(fn, 'w') as file: _ = file.write("hello world!")

with open(fn, 'r') as file: while True: s = file.readline() if s == "": break print(s)

os.remove(fn)

test_open() #> hello world!

def show_tempfile(): with NamedTemporaryFile() as file: _ = file.write(b"test!") # in binary mode

s="" with TemporaryDirectory() as name: s = name assert len(s) != 0

show_tempfile()

class Example(object): # Mimic simple Python "classes". """Example class with Python-ish Nim syntax!.""" start: int stop: int step: int def init(self, start, stop, step=1): self.start = start self.stop = stop self.step = step

def stopit(self, argument): """Example function with Python-ish Nim syntax.""" self.stop = argument return self.stop

def exa(): e = Example(5, 3) print(e.stopit(5))

exa() #> 5

Nimpylib heavily relies on Nim generics, converters, operator overloading, and even on concepts.

Check the Examples folder for more examples. Have more Macros or Templates for Python-like syntax, send Pull Request.

Installation

If the installing is stuck with:Downloading https://github.com/Yardanico/nimpylib using gitPlease note your nimble package.json is outdated, and that old URL is 404 now 2. Run nimble refresh to fetch a newer package.json

Of course, a workaround is to install with full URL:

nimble install https://github.com/nimpylib/pylib

Uninstall with nimble uninstall pylib.

Requisites

Supported features

Features cannot be implemented

However, due to Nim's AST astrict3, a few syntaxes of Python cannot be implemented.

See here for details and workaround.

Other Python-like modules

Tests

This is one snippest from version 0.9.5:

as too much tests output is it, and it's not suitable to list too much content in README, the following demo is not likely to be updated from then on.

$ nimble test [Suite] datetime [OK] utcoffset [OK] attrs [OK] isoformat

[Suite] fromisoformat [OK] if reversible

[Suite] timedelta [OK] init [OK] float init [OK] normalize [OK] stringify

[Suite] date [OK] fromisocalendar [OK] fromisocalendar_value_errors [OK] ordinal_conversion [OK] replace [OK] strftime [OK] ctime

[Suite] tzinfo [OK] fromtimestamp

[Suite] gamma [OK] gamma(-integer)

[Suite] ldexp

[Suite] sumprod [OK] array [OK] CPython:test_math.testSumProd

[Suite] constants [OK] nan [OK] inf

[Suite] classify [OK] isinf [OK] isfinite

[Suite] nextafter_ulp [OK] nextafter [OK] ulp

[Suite] ldexp [OK] static [OK] small [OK] non-normal first arg [OK] large second arg

[Suite] ErrnoAttributeTests [OK] using_errorcode [OK] touch, unlink, is_file [OK] Lib/tempfile [OK] Lib/time [OK] Lib/timeit

[Suite] Lib/array [OK] py3.13: 'w' Py_UCS4 [OK] bytes [OK] cmp [OK] byteswap

[Suite] os.path [OK] if export right [OK] getxtime

[Suite] Lib/os with no JS support [OK] mkdir rmdir [OK] open fdopen close [OK] get,set_inheritable [OK] getattr/set/has [OK] bytearray

[Suite] bytes [OK] getitem [OK] meth [OK] repr

[Suite] complex.init(str) [OK] from str [OK] negative_nans_from_string

[Suite] complex [OK] init [OK] literals [OK] str [OK] op

[Suite] complex.repr [OK] (N+nanj) [OK] real == 0.0

[Suite] complex.pow [OK] CPython:test_complex.ComplexTest.test_pow [OK] with small integer exponents [OK] decorator [OK] custom decorator [OK] dict

[Suite] float.fromhex [OK] literals [OK] nans [OK] some values [OK] overflow [OK] zeros and underflow [OK] round-half-even

[Suite] float.fromhex and hex [OK] roundtrip

[Suite] float [OK] hex [OK] test_nan_signs [OK] is_integer [OK] as_integer_ratio

[Suite] rewrite as py stmt [OK] rewrite in def [OK] rewrite raise [OK] Floor division [OK] int.{from,to}_bytes [OK] io & with [OK] bltin iters [OK] iters as iterable [OK] iter/next [OK] random [OK] Lib/string [OK] list shallow [OK] list.sort [OK] list methods [OK] Python-like types [OK] divmod [OK] pass [OK] lambda [OK] walrus operator [OK] hex() [OK] chr() [OK] oct() [OK] ord() [OK] bin() [OK] Modulo operations [OK] int(x[, base]) [OK] float(str) [OK] Range-like Nim procedure [OK] str.format [OK] str operations [OK] str index [OK] str methods [OK] str.maketrans&translate [OK] tonim macro [OK] unpack macro [OK] With statement [OK] generics in func signature [OK] generics in class's methods [OK] set PASS: tests/testaments/builtins/print.nim c ( 1.93 sec) SKIP: tests/testaments/builtins/print.nim js PASS: tests/testaments/builtins/print_ct.nim c ( 1.93 sec) PASS: tests/testaments/builtins/zip_no_seq.nim c ( 1.96 sec) PASS: tests/testaments/builtins/zip_more_args.nim c ( 0.65 sec) PASS: tests/testaments/builtins/filter_toseq_deadloop.nim c ( 0.66 sec) Used D:\software\scoop\shims\nim.exe to run the tests. Use --nim to override. PASS: tests/testaments/pysugar/colonToSlice.nim c ( 2.75 sec) SKIP: tests/testaments/pysugar/colonToSlice.nim js PASS: tests/testaments/pysugar/strlitCat.nim c ( 1.92 sec) SKIP: tests/testaments/pysugar/strlitCat.nim js PASS: tests/testaments/pysugar/tripleStrTranslate.nim c ( 0.84 sec) PASS: tests/testaments/pysugar/autoSetListDict.nim c ( 3.40 sec)

  1. Some of features (listedhere) and Libs (listedhere) is not available for JS backend yet.
  2. see wiki-history for details
  3. Mostly because they cannot form valid AST in Nim.