Skip to content

Dependencies & shortnames

Most real NodeSets build on others. -e is how you declare them, and the shortname identifies its namespace. Custom declarations also specify the runtime package that the generated code imports.

Declare every dependency

Pass every NodeSet your model needs, including transitive dependencies. They are not selected automatically. For example, if your model depends on Machinery and DI:

ncc python MyMachine.NodeSet2.xml \
    -e ns0 \
    -e di \
    -e machinery \
    -o ./generated

A missing declaration can produce a diagnostic such as:

namespace http://opcfoundation.org/UA/DI/ has no supplied model binding

Binding the base OPC UA namespace is effectively mandatory — every NodeSet references ns0 reference types like HasProperty and HasComponent. Use -e ns0; custom replacements of the standard namespace are unsupported.

Bundled companion specs

ncc python B.xml -e ns0 -e di -o generated uses dependency XML shipped with the compiler. pyncc accepts the same declaration. No dependency checkout or network access is needed. The generated application imports o6.ns.ns0 as ns0 and o6.ns.di as di and needs the corresponding o6\Python runtime packages.

See the list of bundled companion specs for names, versions and model URIs, and compatibility for the runtime baseline. Historical names select distinct versions even when their Model URIs match. Source-only entries cannot be used as runtime shorthand.

Custom dependency locations

Each custom declaration supplies a shortname, a runtime parent package prefix, and an XML source. The shortname is appended to the prefix exactly once:

Declaration Generated import
-e 'a@myproject.ns=A.NodeSet2.xml' import myproject.ns.a as a
-e 'a@=A.NodeSet2.xml' import a as a

Bare XML paths and SHORTNAME=PATH are not accepted for o6\Python dependencies.

The module leaf must be the shortname. For example, a@myproject.ns.a=A.xml means myproject.ns.a.a; it does not independently rename the leaf. Here, A and B depend on ns0; C depends on A, B and DI. The XML files are in the project/ directory:

cd project

ncc python A.NodeSet2.xml --shortname a -e ns0 -o ./generated
ncc python B.NodeSet2.xml --shortname b -e ns0 -o ./myproject/ns
ncc python C.NodeSet2.xml --shortname c \
            -e ns0 -e di \
            -e 'a@generated=A.NodeSet2.xml' -e 'b@myproject.ns=B.NodeSet2.xml' \
            -o ./generated

The commands generate the packages directly into this layout:

project/
├── generated/
│   ├── a/
│   └── c/
└── myproject/
    └── ns/
        └── b/

The generated c package imports generated.a and myproject.ns.b. Use valid Python identifiers for package names and shortnames. A shortname must identify the same namespace throughout the application.

Target names

The target's package and namespace shortname are selected in this order:

  1. --shortname, when supplied.
  2. The pinned shortname for its Model URI.
  3. The input filename stem, lowercased with non-alphanumeric characters replaced by underscores. Leading and trailing underscores are stripped; an empty result becomes model, and a leading digit receives an underscore prefix.

For example, MyMachine.NodeSet2.xml defaults to mymachine_nodeset2 if its URI has no pinned name. Set --shortname mymachine to choose a stable name explicitly.

Use the same shortname in targets and dependencies

A shortname appears in package imports and node IDs throughout your application. For a custom dependency, supply the same name explicitly in its -e declaration. No dependency name is inferred from its filename or Model URI.

Generation and runtime requirements

Dependency XML supplied with -e is sufficient for generation. The compiler resolves dependency datatypes and their ancestry from that XML, including aliases and inherited structures, without importing generated dependency packages. You can generate a model before generating its dependencies.

Generation, including initial values, uses the supplied and bundled XML definitions. The o6\Python runtime and generated dependency packages are needed when you run the output; they do not need to be installed for compilation. An unsupported datatype fails with a diagnostic identifying the datatype and its missing XML definition or ancestry.

Normally, ncc writes directly into your project using -o, with locations matching the imports declared by -e. Running the application from that project needs no additional configuration.

If generated packages are kept outside the project, PYTHONPATH can make that location available at runtime (POSIX shell):

PYTHONPATH=/path/to/generated/nodesets

Using your own build of a stock spec

The compiler warns when a generated target or custom -e declaration reuses a bundled companion-spec shortname, such as di. Generation continues with the chosen name. This also applies to automatically derived target names; bundled declarations such as -e di do not warn.

Use a distinct shortname and an explicit import location for your own build:

cd project

ncc python OldDi.NodeSet2.xml --shortname custom_di -e ns0 -o ./myproject/ns
ncc python MyMachine.NodeSet2.xml -e ns0 \
    -e 'custom_di@myproject.ns=OldDi.NodeSet2.xml' -o ./generated

The generated application imports myproject.ns.custom_di.