test_sys_path
Hosted unit tests for pyRevit's sys.path management.
Run from Revit via the DevTools "Run All Tests" aggregator. Covers the
dedupe-on-insert contract (pyrevit.add_to_sys_path,
pyrevit.dedupe_sys_path) and asserts the invariant on the live
sys.path of the running engine: no folder appears twice.
The live assertion is the one that matters. The helpers are only half the
fix, because IronPython's clr.AddReferenceToFileAndPath appends the
referenced assembly's folder to sys.path itself, once per call, and
pyRevit references several assemblies from the one engine folder. #3687.
The text-type filter is tested against every text type the running engine
actually exposes. pyRevit's patched IronPython unifies str and
unicode into one type, so on that engine a unicode-specific repeat
cannot exist and the cases that need one skip rather than pass quietly.
Attributes
basestring = str
module-attribute
needs_separate_unicode = unittest.skipIf(str is _UNICODE_TYPE, 'this engine unifies str and unicode, so a unicode-only repeat cannot exist')
module-attribute
Classes
SysPathDedupeTests
Bases: TestCase
Contract of pyrevit.add_to_sys_path and pyrevit.dedupe_sys_path.
Methods:
setUp()
Snapshot sys.path so each test can mutate it without leaking.
These tests append and delete real entries, so the engine's own search order has to survive the suite intact.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
tearDown()
test_adds_a_new_folder_once()
Adding the same folder twice leaves one entry.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_skips_a_folder_already_on_sys_path()
A folder the loader already put on sys.path is not appended again.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_is_case_insensitive()
A folder differing only in case is the same folder on Windows.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_keeps_the_first_occurrence_order()
Dedupe drops repeats without reordering the surviving entries.
Order is the module-resolution priority, so collapsing duplicates must not move anything.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_skips_paths_that_are_not_folders()
Missing, empty and None paths never reach sys.path.
A stale entry that resolves to nothing makes the path list lie about what is searchable without contributing anything.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_text_types_cover_every_text_type_this_engine_has()
The filter accepts every text type the running engine exposes.
Runs everywhere, and is what catches a narrowing back to (str,):
on an engine where unicode is a separate type, dropping it makes
a unicode repeat invisible to the dedupe.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_accepts_a_unicode_folder()
A unicode folder is registered, and only once.
IronPython 2 makes str and unicode unrelated types, so a
filter that accepts one silently drops the other - and a dropped
entry is a repeat the dedupe never sees.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_repeated_unicode_entries_are_counted()
The live assertion itself must see a repeated unicode entry.
Guards the assertion rather than the code under it: if
_repeated() skipped unicode entries it would report nothing and
both live-path tests would pass on a path list that does have a
repeat.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_dedupe_drops_a_repeated_unicode_entry()
dedupe_sys_path removes a repeat held as a unicode entry.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
EngineDirectoryTests
Bases: TestCase
pyrevit.ENGINES_DIR must name the folder that holds the engine.
Methods:
test_engine_directory_is_on_sys_path_once()
The engine folder is reachable, and listed exactly once.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
test_engine_directory_exists()
ENGINES_DIR is a real directory.
It used to be assembled as bin/<net>/engines/<engine version> -
a version number rather than a folder name - so it pointed at a path
that does not exist while the real engine folder sat elsewhere.
Source code in pyrevitlib/pyrevit/unittests/test_sys_path.py
LiveSysPathTests
Bases: TestCase
The invariant on the running engine's own sys.path.
Methods:
test_no_folder_is_repeated()
Nothing on the live sys.path is listed twice.
test_dedupe_is_a_no_op_on_a_clean_path()
Dedupe leaves an already-clean sys.path byte-for-byte identical.
test_rpw_import_does_not_restore_a_repeat()
Importing rpw.ui.forms.resources leaves the invariant intact.
That module references the IronPython and WPF assemblies by path, which on IronPython appends the engine folder to sys.path - after framework.py has already collapsed it.