Skip to content

Latest commit

 

History

History
619 lines (457 loc) · 27.5 KB

File metadata and controls

619 lines (457 loc) · 27.5 KB

m2py Parser Limitations

This document describes known limitations of the m2py parser and commands that are not currently supported. Each limitation has a unique ID (LIM-XXX) for traceability to test files.

Limitation Types

Type Description m2py Behavior
Parse Error Syntax is recognized but explicitly rejected Parser raises MUMPSParseError
Parses OK Syntax is valid but runtime/codegen behavior is undefined Parser accepts, codegen may be incomplete
Informative No executable syntax exists No tests needed, comment-only files

Limitation Index

ID Category Type Description
LIM-001 Event Processing Commands Parse Error ABLOCK, AUNBLOCK, ASTART, ASTOP, ESTART, ESTOP, ETRIGGER
LIM-002 THEN Command Parse Error Zero real-world usage
LIM-003 MWAPI SSVNs Parses OK ^$EVENT, ^$WINDOW, ^$DISPLAY (X11.6 standard)
LIM-004 Deprecated Functions Parses OK $DEXTRACT, $DPIECE (never standardized)
LIM-005 VIEW Command Parses OK Implementation-defined keywords
LIM-006 Extended Character Sets Parses OK Implementation-defined charset operations
LIM-007 BNF Metalanguage Informative §5 is informative only, no executable syntax
LIM-008 Embedded Programs Informative §6.4 out of scope for source-to-source transpiler
LIM-009 RLOAD/RSAVE Commands Parse Error Zero real-world usage
LIM-011 ^$LIBRARY SSVN Parses OK Zero real-world usage, runtime undefined
LIM-012 Unknown Z-Extensions Parse Error Unknown Z-commands/functions from other implementations
LIM-013 ASSIGN Command Parse Error Part of MWAPI event model
LIM-014 ANSI Standard Library Functions (Annex I) Parses OK ~60 library functions with zero VistA usage
LIM-015 YDB-Specific Features Parses OK YDB-specific commands, functions, and behaviors
LIM-016 Zero-VistA-Usage Deferred Features Parses OK Features with confirmed zero VistA usage
LIM-017 Partial IRIS/Caché Support Parses OK Subset of IRIS/Caché vendor functions used by VistA
LIM-019 Arithmetic Precision Edge Cases Parses OK Minor precision differences in 18-digit boundary cases

Unsupported MUMPS Commands

Unknown Command Handling

Commands that don't match any recognized MUMPS command will produce a clear error:

MUMPSUnknownCommandError: Unknown command 'FOOBAR'. Not a recognized MUMPS command or valid abbreviation.

This error will be triggered for:

  • Misspelled command names
  • Vendor-specific extensions (e.g., InterSystems Caché/IRIS proprietary commands)
  • Event processing commands (see LIM-001)

LIM-001: Event Processing Commands

Type: Parse Error

The following commands are defined in ANSI M X11.1-1995 for event-driven programming but are not implemented. These commands have zero usage in both the YottaDB test suite and VA Vista codebase, suggesting they are not used in production MUMPS systems:

Command Description
ABLOCK Block asynchronous events during critical sections
AUNBLOCK Unblock asynchronous events
ASTART Start asynchronous event processing
ASTOP Stop asynchronous event processing
ESTART Start synchronous event processing
ESTOP Stop synchronous event processing
ETRIGGER Trigger an event

m2py Behavior: Parser raises MUMPSParseError for these commands.

LIM-002: THEN Command

Type: Parse Error

The THEN command is a standard MUMPS command but has zero usage in YottaDB tests and VA Vista. It will be implemented if encountered in real codebases.

m2py Behavior: Parser raises MUMPSParseError.

LIM-009: RLOAD/RSAVE Commands

Type: Parse Error

The RLOAD (Routine Load) and RSAVE (Routine Save) commands are defined in ANSI M X11.1-1995 §8.2.17 and §8.2.18 for dynamic routine management at runtime. These commands have zero usage in both the YottaDB test suite and VA VistA codebase.

m2py Behavior: Parser raises MUMPSParseError.

LIM-012: Unknown Z-Extensions

Type: Parse Error

Per the MUMPS standard, all names beginning with 'Z' are reserved for vendor-specific extensions (FR-017). m2py implements support for:

YottaDB Z-commands: ZBREAK, ZCOMPILE, ZGOTO, ZHALT, ZHELP, ZKILL, ZLINK, ZLOAD, ZMESSAGE, ZPRINT, ZSHOW, ZSTEP, ZSYSTEM, ZTRIGGER, ZWRITE, ZALLOCATE, ZDEALLOCATE.

YottaDB Z-functions: $ZDATE, $ZSEARCH, $ZVERSION, $ZREFERENCE, etc.

IRIS/Caché functions (partial, see LIM-017): $ZBOOLEAN, $ZCONVERT/$ZCVT, $ZF(-1/-2/-100), $ZU (selected codes). These are parsed and produce working generated code for the subset of features used by VA VistA.

m2py Behavior: Known YottaDB and IRIS/Caché Z-extensions are parsed and produce ASG nodes. Unknown Z-commands or Z-functions from other MUMPS implementations (MicroM, DSM, etc.) raise MUMPSParseError. See LIM-017 for IRIS/Caché support scope.

LIM-013: ASSIGN Command

Type: Parse Error

The ASSIGN command is defined in ANSI M X11.1-1995 for structured system variable assignment as part of the MWAPI event model. It has zero usage in both the YottaDB test suite and VA VistA codebase.

m2py Behavior: Parser raises MUMPSParseError.

Vendor-Specific Commands

m2py targets standard MUMPS with YottaDB/GT.M extensions. Commands specific to other implementations (InterSystems Caché/IRIS, MicroM, DSM, etc.) are not currently supported and will trigger the unknown command error.

If you encounter a command that should be supported, please open an issue.

LIM-003: MWAPI SSVNs

Type: Parses OK

The MUMPS Windowing API (MWAPI, defined in ANSI M X11.6) provides GUI capabilities through structured system variables and event processing. m2py does not support MWAPI because:

  1. Limited real-world usage - Only 5 files in VA VistA reference MWAPI (ZISG*.m)
  2. Separate standard - MWAPI is a distinct specification (X11.6) from core MUMPS (X11.1)

Unsupported MWAPI Structured System Variables

SSVN Description
^$WINDOW Window definitions and properties
^$DISPLAY Display/screen information
^$EVENT Event information for GUI callbacks

Unsupported MWAPI Commands

Event processing commands (ABLOCK, AUNBLOCK, ASTART, ASTOP, ESTART, ESTOP, ETRIGGER) listed above are also part of the MWAPI event model.

m2py Behavior: Parser accepts ^$EVENT, ^$WINDOW, ^$DISPLAY syntax (valid SSVN grammar). ASG produces MStructuredSystemVariable. Codegen raises NotImplementedError("LIM-003: MWAPI SSVNs not supported").

LIM-004: Deprecated Functions

Type: Parses OK

These functions were proposed for the 1984/1990 standards but never included in the final ANSI standard. They follow valid intrinsic function syntax.

m2py Behavior: Parser accepts $DEXTRACT and $DPIECE (valid function syntax). ASG produces MFunctionCall. Codegen behavior is undefined as these functions have no standard semantics.

LIM-005: VIEW Command

Type: Parses OK

The VIEW command is defined in ANSI M X11.1 §8.2.24 as having "arguments unspecified" - meaning the syntax and behavior are entirely implementation-specific. Each MUMPS implementation (YottaDB, GT.M, Caché, etc.) defines its own VIEW keywords and semantics.

Parser accepts VIEW commands with YottaDB/GT.M syntax:

  • VIEW "keyword" - Simple keyword
  • VIEW "keyword":value - Keyword with value
  • VIEW "keyword":value1:value2 - Keyword with multiple colon-separated values
  • VIEW expr - Expression form

Common YottaDB VIEW keywords: BADCHAR, BREAKMSG, GDSCERT, GVDUPSETNOOP, LVNULLSUBS, NOUNDEF, PATCODE, TRACE, etc.

m2py Behavior: The ASG produces MViewStatement with raw arguments preserved. Code generation must handle VIEW commands on a per-implementation basis since semantics vary significantly between MUMPS platforms.

LIM-006: Extended Character Sets

Type: Parses OK

The MUMPS 1995 standard defines a base character set profile "charset M" (Annex A) which uses ASCII codes 0-127. Extended character sets (Unicode, UTF-8, ISO 10646, vendor-specific charsets) are defined through the ^$CHARACTER structured system variable and are implementation-specific.

Per §9 (Character Set Profile), a charset defines:

  1. Character codes and their meaning
  2. Valid characters for names (identifiers)
  3. Available pattern codes and definitions
  4. Collation order for string comparison

Charset naming conventions:

  • Names beginning with Y - Reserved for user-defined charsets
  • Names beginning with Z - Reserved for vendor-defined charsets
  • All other names - Reserved for future standard enhancement

YottaDB Unicode support: YottaDB provides UTF-8 mode via the ydb_chset environment variable, but the specific character handling behaviors are outside the scope of standard MUMPS and must be handled at code generation time.

m2py Behavior: m2py implements charset M (ASCII 0-127) as the default. Extended character sets beyond ASCII are not fully supported. String handling assumes ASCII/UTF-8 compatibility. The ^$CHARACTER SSVN is parsed but charset-specific operations (transforms, collation algorithms) are implementation-defined.

LIM-007: BNF Metalanguage

Type: Informative

Section 5 of the MUMPS standard describes the BNF notation used throughout the specification. This section is informative only and contains no executable semantics to implement or test.

m2py Behavior: No parser or ASG implementation needed. Test files contain comments only, documenting this as informational content.

LIM-008: Embedded Programs

Type: Informative

Section 6.4 defines rules for embedding MUMPS code within other programming languages (e.g., C, FORTRAN). This involves host language interoperability, foreign function interfaces, and runtime integration that is outside the scope of a source-to-source transpiler.

m2py Behavior: Not applicable. m2py transpiles standalone MUMPS routines to Python, not MUMPS embedded within other host programs. Test files contain comments only.

LIM-011: ^$LIBRARY SSVN

Type: Parses OK

The ^$LIBRARY SSVN provides access to routine library information. This has zero usage in the VA VistA codebase.

m2py Behavior: Parser accepts ^$LIBRARY syntax (valid SSVN grammar). ASG produces MStructuredSystemVariable. Codegen raises NotImplementedError("LIM-011: ^$LIBRARY SSVN not supported").

LIM-014: ANSI Standard Library Functions (Annex I)

Type: Parses OK

ANSI M X11.1-1995 Annex I defines standard library functions organized into three routines: ^MATH, ^STRING, and ^CHARACTER. These are extrinsic functions called as $$%FUNC^ROUTINE(args). However, VA VistA has zero usage of any ANSI standard library functions. VistA instead uses its own Kernel Library Functions (^XLFMTH, ^XLFHYPER, ^XLFCRC, etc.).

Unimplemented ANSI Library Functions

Routine Functions Count
^CHARACTER COLLATE, COMPARE 2
^STRING CRC16, CRC32, CRCCCITT, FORMAT, LOWER, UPPER, PATCODE 7
^MATH (Extended) Hyperbolic: SINH, COSH, TANH, COTH, SECH, CSCH 6
^MATH (Extended) Inverse Hyperbolic: ARCSINH, ARCCOSH, ARCTANH, ARCCOTH 4
^MATH (Extended) Extended Trig: COT, CSC, SEC, ARCCOT, ARCCSC, ARCSEC 6
^MATH (Extended) Angle Conversion: DEGRAD, RADDEG, DECDMS, DMSDEC 4
^MATH (Extended) Complex Numbers: CABS, CADD, CSUB, CMUL, CDIV, CSIN, CCOS, CEXP, CLOG, CPOWER, COMPLEX, CONJUG 12
^MATH (Extended) Matrix: MTXADD, MTXSUB, MTXMUL, MTXINV, MTXDET, MTXTRP, MTXCOPY, MTXSCA, MTXEQU, MTXCOF, MTXUNIT 11
^MATH (Extended) Miscellaneous: ABS, SIGN, PI, E, PRODUCE, REPLACE, XOR 7

Total: ~59 unimplemented functions

Note: Core math functions (EXP, LOG, SQRT, SIN, COS, TAN, ARCSIN, ARCCOS, ARCTAN) and their aliases (LN, ASIN, ACOS, ATAN) are implemented via the bundled %MATH routine in m2py.runtime.routines.MATH.

m2py Behavior: Parser accepts extrinsic function syntax $$%FUNC^ROUTINE(args) (valid grammar). ASG produces MExtrinsicFunction. Code generation behavior:

  • STRING, CHARACTER libraries: Raises NotImplementedError("LIM-014: ...")
  • MATH library - unimplemented functions: Raises NotImplementedError("LIM-014: ...")
  • MATH library - implemented functions: Generates working code using bundled MATH.py

VistA codebases work correctly as they use Kernel Library Functions (^XLFMTH, etc.) instead of ANSI standard library routines.

LIM-015: YDB-Specific Features

Type: Parses OK

YDB-specific features. Some are fully implemented, some are parsed but produce stub codegen, and some require YDB infrastructure not available in transpiled code.

Implemented Z-Commands (generate working Python code):

Command Description Codegen
ZLINK / ZLOAD Compile and link routines No-op stub (pass)
ZSHOW Display environment info Full implementation for I/S/D
ZPRINT Print routine source No-op stub (pass)
ZMESSAGE Signal error condition raise RuntimeError
ZGOTO Non-local goto with level Full trampoline support
ZWRITE Write local variables Full implementation
ZHALT Halt with exit code Full implementation
ZKILL Kill exclusive Full implementation

Stub Z-Commands (parsed, generate no-op or error):

Command Description VistA Files Codegen
ZSYSTEM Execute OS command ~6 No-op stub
ZBREAK Set breakpoints 4 No-op stub
ZSTEP Single-step debug 1 No-op stub

Implemented Z-Functions / Z-Special Variables:

Function/Variable Description Status
$ZVERSION/$ZV Version string Returns m2py version
$ZTRAP/$ZT Error trapping Full implementation
$ZSTATUS/$ZS Last error status Full implementation
$ZDATE Date formatting Full implementation
$ZPOSITION/$ZPO Error location Full implementation
$ZEOF End-of-file flag Full implementation
$ZJOB Job/process info Full implementation
$ZSEARCH File search Full implementation
$ZREFERENCE/$ZR Last global reference Full implementation
$ZERROR/$ZE Last error string Full implementation
$ZINTERRUPT/$ZINT Interrupt handler SET and read supported
$ZSOURCE/$ZSO Source file name SET and read supported
$ZGBLDIR Global directory SET and read supported
$DEVICE/$D Device status Read-only, returns ""
$REFERENCE/$R Last global reference Read-only, alias for $ZR
$ZMESSAGE Error message lookup Full implementation
$ZSORT Collation-aware $ORDER Alias for $ORDER (DSM/VMS)
$ZABS Absolute value Full implementation
$NOW Current $H-format timestamp Full implementation
$ZBITOR/$ZBITXOR/$ZBITNOT Bitwise byte-string ops Full implementation
$ZGETDVI Device info (DSM/VMS) Stub, returns ""
$ZGETSYI System info query Returns hostname for NODENAME
$ZTIME/$ZT(expr) Format seconds as HH:MM:SS Full implementation
$ZDIR Current directory path Returns os.getcwd()
$ZGLD Global directory path Stub, returns ""
$ZTIMEZONE Timezone offset (seconds) Returns time.timezone
$ZTIMESTAMP UTC $H-format timestamp Returns $HOROLOG (UTC stub)
$ZLEVEL/$ZL Stack depth Stub, returns 1
$ZDIRECTORY/$ZD (GET) Current working directory Returns os.getcwd()
$ZDIRECTORY/$ZD (SET) Change working directory os.chdir()
$ZPIECE $PIECE alias (GT.M/YDB) Alias for $PIECE
$ZBITSTR Bit string constructor Full implementation (YDB format)
$ZCO $ZCONVERT abbreviation Alias for $ZCONVERT
$ZSIGPROC Process signal Stub, returns "1"
SET $ZSTEP Single-step trap handler No-op stub

Not Implemented Z-Functions / Z-Special Variables:

Function/Variable Description VistA Files
$ZRO Routine search path 10
$ZWIDTH String width 1

Z-Commands / Z-Functions with zero VistA usage:

Command/Function Description VistA Files
ZALLOCATE Resource allocation 0
ZDEALLOCATE Resource deallocation 0
ZCOMPILE Compile routines 0
ZCONTINUE Continue from break 0
ZEDIT Edit routine 0
ZHELP Display help 0
ZTRIGGER Trigger management 0

YDB Utilities:

Utility Description VistA Files
^%G Global display utility 6

YDB Runtime Behaviors (not implementable without YDB infrastructure):

Feature Description VistA Files
BREAK command Requires YDB interactive debugger 662
Numeric overflow errors YDB raises errors for numbers >1E47 N/A
Device parameters YDB-specific OPEN/USE device parameters N/A
Test harness infrastructure JOBLABOFF, pre-populated databases N/A

Features with zero VistA usage are deferred indefinitely.

VistA-VEHU-M Coverage: As of Phase 14, the transpiler handles 39,299 out of 39,304 VistA routines (99.99%). The 5 remaining failures are:

  • 4 MWAPI routines (LIM-003: ^$EVENT/^$WINDOW/^$DISPLAY SSVNs)
  • 1 malformed source file (ZZBACSUA)

m2py Behavior: Parser accepts Z-commands (valid YDB grammar). ASG produces appropriate nodes. Implemented features generate working Python code. Stub features generate no-op or error-signaling code. Unimplemented features raise NotImplementedError("LIM-015: {feature} not supported"). YDB-specific runtime behaviors are not implemented.

LIM-016: Zero-VistA-Usage Deferred Features

Type: Parses OK

The following features are syntactically supported but have confirmed zero usage in the VA VistA codebase (33,951 routine files analyzed). Implementation is deferred indefinitely due to lack of real-world demand:

Feature Description VistA Usage Status
KSUBSCRIPTS Kill subscripted descendants only (ANSI) 0 files Not in YDB
KVALUE Kill root value only (ANSI) 0 files Not in YDB
TROLLBACK:n Rollback to specific transaction level 0 files Syntax parsed
$TRESTART Transaction restart count special variable 0 files Syntax parsed
Module caching Python module import caching optimization N/A Performance only

Note: KSUBSCRIPTS and KVALUE are ANSI MUMPS commands (§8.2) that YottaDB does not implement. Since m2py targets YDB compatibility, these commands raise NotImplementedError.

m2py Behavior: Parser accepts syntax. ASG produces appropriate nodes. Codegen raises NotImplementedError("LIM-016: {feature} not supported").

LIM-017: Partial IRIS/Caché Support

Type: Parses OK

m2py implements partial support for InterSystems Caché/IRIS vendor-specific functions as used by VA VistA. This covers the subset of IRIS features actually used in VistA-VEHU-M routines. IRIS features not used by VistA are not supported.

Fully Implemented

Function Description Semantics
$REPLACE String replacement Full IRIS-compatible (start, count, case params)
$ZBOOLEAN 16-op bitwise Boolean Integer and string modes
$ZCONVERT/$ZCVT String case conversion U, L, S, W, T modes
$ZF(-1) Execute OS command subprocess.run, returns exit code
$ZF(-2) Launch background process subprocess.Popen, returns 0
$ZF(-100) Execute with flags subprocess.run with flag parsing

Read-Only Special Variables

Variable Description Default
$ZVERSION/$ZV Version string "m2py for Python 1.0..."
$ZA I/O activity status 0
$ZREFERENCE/$ZR Last global reference "" (tracks SET/GET/KILL)
$DEVICE/$D Device status ""
$REFERENCE/$R Last global reference (alias for $ZR) ""

Settable Special Variables

Variable Read SET NEW
$NAMESPACE
$ZREFERENCE/$ZR
$ZINTERRUPT/$ZINT
$ZSOURCE/$ZSO
$ZGBLDIR

Dispatch Tables

Function Implemented Codes Description
$ZU 0, 5, 12, 53, 56, 68, 140, 168, 190 VistA-used utility codes

Stubs (return "" with warning)

Function Description
$&/$ZCALL External C function calls
$VIEW/$V (function form) Implementation-defined view

Not Implemented

Feature Description
Other $ZU codes Unrecognized codes raise warning, return ""
$ZF("GETSYM"/"GETJPI"/"TRNLNM") VMS-specific stubs, return ""
IRIS class methods ##class(...) syntax not supported
IRIS SQL embedding Embedded SQL not supported

m2py Behavior: Implemented IRIS features generate working Python code with correct semantics. Stub features return empty string with a warning. Unrecognized $ZU codes log a warning and return empty string. IRIS-specific language extensions (class methods, SQL embedding) are not supported and raise parse errors.

LIM-019: Arithmetic Precision Edge Cases

Type: Parses OK

MUMPS specifies 18 significant digits for numeric precision. m2py uses Python's Decimal library to implement this precision. However, there are minor differences in edge cases when results approach the 18-digit boundary:

Case YDB m2py Difference
-1 + .000000000000000001 -1 -.999999999999999999 Rounding to integer
-37 * 1.00000000111111111 -37.000000041111111 -37.0000000411111111 Last digit

These differences affect the YDB arith.m test which implements its own bignum arithmetic and compares against the built-in operators. Both implementations are correct to 18 significant digits; the difference is in rounding behavior at the precision boundary.

Real-world MUMPS code rarely depends on the exact 18th significant digit.

Test Coverage: Comprehensive unit tests for arithmetic helper functions (m_add, m_sub, m_mul, m_div) are in tests/unit/codegen/test_helpers.py. All test cases are verified against YDB output and cover:

  • Basic operations, zero handling, negative numbers
  • Decimal precision (avoiding float errors like 0.1+0.2)
  • String coercion via m_num
  • 18-digit precision for repeating decimals
  • Result formatting via m_str (no scientific notation)

m2py Behavior: Arithmetic operations produce correct results to 18 significant digits. Edge case rounding may differ slightly from YDB in the last significant digit.


Backend-Specific Limitations

Database Limits by Backend

Limit InMemory/SQLite YottaDB IRIS
Max global name length Unlimited 31 chars (incl. ^) 31 chars (incl. ^)
Max subscript length Unlimited 1,019 bytes 511 bytes
Max subscript depth Unlimited 31 levels 255 levels
Max key length (name + all subscripts) Unlimited 1,019 bytes total 511 bytes per subscript
Max node value size Unlimited 1 MiB 3,641,144 chars (~3.5 MiB)
Max subscripts per global ref Unlimited 31 255
Numeric precision Python Decimal (28 digits) 18 significant digits 18 significant digits (IEEE double)
Empty string subscripts Allowed Allowed Not allowed (raises <SUBSCRIPT>)

YottaDB-Specific Limitations

Feature Limitation Workaround
LOCK semantics yottadb.lock() replaces all held locks Backend tracks locks in _locks_held dict and re-acquires on unlock
Transaction model Uses yottadb.tp() callback model (not imperative start/commit) Backend adapts imperative API to callback model internally
Connection In-process only (C extension, no TCP) Must run inside YDB container via utils/ydb.sh
Thread safety SDK is not thread-safe All calls serialized via threading.Lock
$INCREMENT in transactions $INCREMENT is non-transactional in YDB Behavior matches MUMPS spec (increments survive rollback)

IRIS-Specific Limitations

Feature Limitation Workaround
Empty string subscripts IRIS raises <SUBSCRIPT> error Tests skip empty subscript cases on IRIS
Extended references `^ "NS"
Namespace switching Single namespace per connection Set M2PY_IRIS_NAMESPACE before connecting
$INCREMENT in transactions $INCREMENT is non-transactional by design Behavior matches IRIS semantics (increments survive rollback)
Connection model TCP connection (higher latency than YDB in-process) Use connection pooling (future) or batch operations
Lock counting Incremental lock (+) counting differs from YDB ssvn_lock nested count test skipped on IRIS
Thread safety IRIS connection is not thread-safe All calls serialized via threading.Lock

SSVN (Structured System Variable) Limitations

SSVN InMemory YottaDB IRIS Notes
^$GLOBAL(name) Checks in-memory store Queries native $DATA Queries native isDefined Full implementation
^$JOB(pid) os.kill(pid, 0) os.kill(pid, 0) os.kill(pid, 0) OS-level check, not database job table
^$LOCK(name) In-memory lock table Python-side _locks_held dict Python-side _locks_held dict Only sees locks held by current process
^$ROUTINE(name) Python module check + .m file Python module check + .m file Python module check + .m file Checks m2py.runtime.routines.* namespace

^$LOCK limitation: The ssvn_lock() implementation only reports locks held by the current process via the Python-side _locks_held tracking dictionary. It does not query the database's native lock table, so locks held by other processes or connections are not visible. This is sufficient for single-process MUMPS transpilation but does not provide the full multi-process ^$LOCK semantics of native MUMPS.

^$JOB limitation: Uses OS-level os.kill(pid, 0) to probe process existence rather than querying the database's native job table. This means it reports on OS processes, not MUMPS jobs specifically.


Limitation Management Workflow

Adding a New Limitation

  1. Assign ID: Use the next available LIM-XXX number
  2. Add to limitations.py: Add entry to LIMITATIONS dict in src/m2py/limitations.py
  3. Regenerate docs: Run uv run python utils/rebuild_docs.py
  4. Check VistA-M usage: Run rg 'PATTERN' VistA-M/ to verify zero usage
  5. Create test: Add parse error test referencing the LIM-XXX ID

Test Requirements

Each limitation MUST have a corresponding test that:

  • References the limitation ID in the docstring (e.g., "See LIM-001")
  • Verifies the parser raises an appropriate error for unsupported syntax
  • Does NOT use @pytest.mark.skip - must be an active passing test

Cross-Reference Format

Tests should reference limitations as:

def test_ablock_raises_parse_error(self):
    """ABLOCK command raises parse error. See LIM-001."""
    with pytest.raises(MUMPSParseError):
        parser.parse(" ABLOCK")