Tutorial
8. Modules and packages
Splitting a program into files#
Every .nox file is a module. A project is a directory with a nox.json:
geometry/
├── nox.json
├── main.nox
├── mathutil.nox
├── mathutil_test.nox
└── shapes/
└── rect.nox{
"name": "geometry",
"version": "0.1.0",
"entry": "main.nox"
}shapes/rect.nox defines a class, mathutil.nox a constant and a function:
# shapes/rect.nox
class Rect:
w: int
h: int
def __init__(self, w: int, h: int) -> None:
self.w = w
self.h = h
def area(self) -> int:
return self.w * self.h# mathutil.nox
SCALE: int = 10
def scaled(n: int) -> int:
return n * SCALEmain.nox imports them:
# main.nox
import mathutil
from shapes.rect import Rect
from mathutil import SCALE
r: Rect = Rect(3, 4)
print(r.area(), mathutil.scaled(5), SCALE)noxc run main.nox12 50 10import mathutilloadsmathutil.noxfrom the project root; call its functions asmathutil.scaled(5).from shapes.rect import Rectloadsshapes/rect.noxand bringsRectinto scope directly.- A module's constants are read with
from mathutil import SCALE. - All the files compile together into one program, and the statements at the top level of
main.noxare what runs.
Using the standard library#
Standard-library modules live under nox.: import nox.strings, from nox.math import sqrt, import nox.json. The full list is the
standard library reference.
import nox.time
from nox.math import sqrt, pi
print(sqrt(16.0), pi() > 3.14, nox.time.now_ms() > 0)4.0 True TrueTests#
noxc test finds every *_test.nox file under the current directory and runs it. A test file is an ordinary program that fails
(raises) when an expectation is wrong:
# mathutil_test.nox
import nox.test
import mathutil
nox.test.assert_eq_int(mathutil.scaled(2), 20, "scaled(2)")
nox.test.assert_true(mathutil.scaled(0) == 0, "scaled(0)")
print("mathutil ok")noxc testThird-party packages#
Packages are ordinary Nox projects in a Git repository. Add one with noxc add, which records it in nox.json:
noxc search http # search the central index
noxc add nyx # add a package by name (the index knows its repository)
noxc fetch # download dependencies; pins exact commits in nox.lock{
"name": "geometry",
"entry": "main.nox",
"requires": [
{ "alias": "nyx", "repo": "github.com/mburakmmm/nyx", "ref": "v0.21.0" }
]
}import nyx.app # module "app" of the package aliased "nyx"nox.lock pins every dependency to an exact commit, so builds are reproducible; commit it to your repository. See
Packages for the full workflow, including noxc update, global installs and publishing your own package.
A package that contains extern def declarations runs native code — read Security before adding
dependencies you do not trust.