SkillAgentSearch skills...

Nimpylib

"Write Python in Nim!" Python builtins/standard-Lib functions ported to Nim

Install / Use

/learn @nimpylib/Nimpylib
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

NimPylib

C Test JS Test Docs Commits

<!--![](https://img.shields.io/github/stars/nimpylib/pylib?style=flat "Star NimPylib on GitHub!") [![Issues](https://img.shields.io/github/issues-raw/nimpylib/pylib?style=flat)](https://github.com/nimpylib/pylib/issues) [![PRs](https://img.shields.io/github/issues-pr-raw/nimpylib/pylib?style=flat)](https://github.com/nimpylib/pylib/pulls)-->

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:

  • use much Python-like out-of-box API in Nim:
    • with no need of any Python dependency (neither dynamic library nor binary).
    • even handy for ones who don't use much Python but want more functions in Nim
  • translate your Python program to Nim:
    • gaining a right-away speed boot of even 700x
    • no worry about binary distribution or packaging, just "compile once, distribute everywhere"
    • rid of many annoying runtime-errors (which are turned to compile-time error)
  • gain a better view into different behaviors between Python and Nim:

Backends

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

[^JS]: Some of features (listed here) and Libs (listed here) is not available for JS backend yet.

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 `def`s?
# 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

nimble install pylib

If the installing is stuck with: Downloading https://github.com/Yardanico/nimpylib using git Please note your nimble package.json is outdated, and that old URL is 404 now [^oldUrl]. 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

[^oldUrl]: see wiki-history for details

Uninstall with nimble uninstall pylib.

Requisites

Supported features

  • [x] F-Strings f"foo {variable} bar {1 + 2} baz"
  • [x] str bytes bytearray list dict set frozenset() with their methods
  • [x] Python-like variable unpacking
  • [x] Math with Float and Int mixed like Python.
  • [x] lambda:
  • [x] class Python-like OOP with methods and DocStrings (without multi-inheritance)
  • [x] @classmethod and @staticmethod
  • [x] with open(fn, [, ...]): Read, write, append, and read(), seek(), tell(), etc.
  • [x] super(...).method(...)
  • [x] global/nonlocal (with some limits)
  • [x] True / False
  • [x] pass
  • [x] del foo[x]
  • [x] := Walrus Operator
  • [x] abs()
  • [x] all()
  • [x] any()
  • [x] ascii()
  • [x] bin()
  • [x] chr()
  • [x] complex()
  • [x] divmod()
  • [x] enumerate()
  • [x] filter()
  • [x] float()
  • [x] format()
  • [x] getattr()
  • [x] hasattr()
  • [x] hash()
  • [x] hex()
  • [x] id()
  • [x] input()
  • [x] int()
  • [x] isinstance()
  • [x] issubclass()
  • [x] iter()
  • [x] list()
  • [x] map()
  • [x] max()
  • [x] min()
  • [x] next()
  • [x] oct()
  • [x] ord()
  • [x] open() (though without close_fd, opener, errors)
  • [x] pow(base, exp, mod=None)
  • [x] print("foo") / print "foo" Python2 like
  • [x] range()
  • [x] reversed(iterable)
  • [x] round()
  • [x] hasattr()
  • [x] set(), also named pyset() to distingish with system.set
  • [x] slice()
  • [x] sorted(iterable)
  • [x] str()
  • [x] sum()
  • [x] != and Python1 <>
  • [x] long() Python2 like (deprecated)
  • [x] u"string here" / u'a' Python2 like
  • [x] b"string here" / b'a'
  • [x] zip(*iterables, strict=False)
  • [x] (WIP) standard libraries math, random, datetime, os, tempfile, timeit, ... (see Lib Docs for all supported)
  • [ ] aiter anext and await (yet async def is supported)
  • More...

Features cannot be implemented

However, due to Nim's AST astrict[^nimInvalidAST], a few syntaxes of Python cannot be implemented.

See here for details and workaround.

[^nimInvalidAst]: Mostly because th

View on GitHub
GitHub Stars62
CategoryDevelopment
Updated5d ago
Forks2

Languages

Nim

Security Score

100/100

Audited on Mar 23, 2026

No findings