- 2026-10-13 -- Two stores the DCC packages carried as hand-kept twins sink here: new
SceneNotes(file_utils/scene_notes.py) andBakeCache(file_utils/bake_cache.py);FileDependenciesgainsreference_bytes,scan_references,open_decompressedand theREFERENCE_READERStable.SceneNotesis the Reference Manager's Notes store -- one<project>/<data rule>/scene_notes.jsonkeyed project-relative, a legacy<scene>.metadata.jsonnote imported on first read, and a newimport_notesfor notes a host kept elsewhere -- moved whole from mayatk and blendertk, which held identical 169-line copies with no drift guard.BakeCacheis the project bake store both bridges kept: one never-aged slot per source inWorkspace.cache_dir("bridge"), the<stem>_<hash8>slot key, the source's content key (source_key, byte-identical to the keys already written, so no existing bake reads as stale),current/write/rehome/source_of, andpurgeby reference. How a record is read from a bake (read_info) and how one is produced (write's andrehome's callables) are injected by the host, so neither DCC branches on the other. The purge's scan isFileDependencies.scan_referencesoverreference_bytes(a.maheader up to its firstcreateNode, a.blenddecompressed -- gzip, zstd throughcompression.zstdor the optionalzstandard-- anything else whole), walkingFileDependencies.walk; a file it cannot read stops the answer (None), never a partial set a purge would delete by. Hardened before release (review 2026-10-13): a notes file that exists but cannot be read -- a sharing lock, corrupt JSON, a document that is not an object -- read as an empty store, so the nextsetwrote one note over every other scene's (and the failed read was cached by mtime); nowsetraisesOSErrorand writes nothing,getreads""and logs,removeandmovelog and write nothing, and a failed read is never cached.movewrites the new note before it drops the old, so a failed write leaves the note where it was. A legacy sidecar is tidied only when it parsed as an object: a JSON list crashed.items(), and an unreadable one was removed. A corrupt zstd frame raised the decoder's ownZstdError-- anException, not anOSError-- out ofreference_bytes,scan_referencesandBakeCache.purge; it reads as unreadable now (None, and the purge refuses), andopen_decompressed's zstd stream raisesOSErrorfor it, as gzip's does.BakeCachebuilds oneCachedArtifactper cache folder instead of one perslot/current/writecall.- Test(s): new
test_scene_notes.py(14),test_bake_cache.py(28),test_file_dependencies.pyTestReferenceBytes+TestScanReferences(11) -- all 53 red before the move;surface_snapshot.jsonupdated (+BakeCache, +SceneNotes). Review fixes:test_scene_notes.pynewTestUnreadableStore(6: corrupt / locked / non-object store, remove, the uncached failed read, move order) andtest_a_non_object_sidecar_is_left_alone,test_an_unreadable_sidecar_is_never_removed(7 red before the fix; the remove pin was green);test_file_dependencies.pynewtest_a_corrupt_zstd_file_is_unreadable_not_an_error(stubcompression.zstdandzstandarddecoders, red);test_bake_cache.pynewtest_a_corrupt_zstd_scene_stops_the_purge_without_raising,test_the_store_is_built_once_per_cache_folder(red).
- Test(s): new
- 2026-10-13 -- A file set aside with no trash goes to a temp store kept 30 days, never a
_supersededfolder left beside the maps (file_utils/file_dependencies.pyFileDependencies.set_aside, newSUPERSEDED_STORE,SUPERSEDED_DAYS;SUPERSEDED_DIRstays walk-skipped for projects that hold one). A re-bake on a network share or a removable drive (a volume with no Recycle Bin) filled the project with_superseded/folders. The file is moved under its own name into a freshTempArtifacts("superseded")folder (copied, then the original removed, across volumes; a held-open file stays where it was) and is still one restore away. Maintainer's decision 2026-10-13, reversing the_superseded/folder decided 2026-09-27: with no trash a superseded file goes to the 30-day temp store, and it is swept for sure -- by the store's first allocation in a process and by the dailyTempArtifacts.sweep_all, the 30 days being pythontk's own guarantee, not the OS temp cleaner's. The file keeps its modification time, so its age counts from its last write. Only a cross-device rename (EXDEV, Windows'ERROR_NOT_SAME_DEVICE) falls back to a copy -- any other refusal (held open, denied) raises with nothing copied -- and a copy cut short is removed with its folder. A batch sets aside through one sweep of the store, not one per file (sweep_interval).- Test(s):
test_file_dependencies.pytest_with_no_trash_it_goes_to_the_temp_store_under_its_name(replaces the beside-itself pin; red: the folder beside the map),TestRemoveSuperseded._asidereads the store. 38/38. Review fixes: newtest_another_volume_is_copied_then_the_original_removed,test_a_rename_refused_for_another_reason_is_not_copied,test_a_failed_copy_leaves_no_partial_file_behind,test_a_batch_sweeps_the_store_once_not_per_file(the last three red).
- Test(s):
- 2026-10-13 -- Every hand-off run gets its own scratch folder, a detached one too (
core_utils/handoff/app_handoff.pyHandoffBridge._scratch_dir). A detached run (a send whose app reads the files after we return) reused ONE fixed<prefix>/<name>folder per bridge, so a second send -- or a second host -- rewrote the files a launched Toolbag or Painter was still reading. It now takes a unique root per run like a scoped one; the store's age sweep bounds the generations.- Test(s):
test_bridge.pytest_detached_run_gets_its_own_folder_and_never_deletes(red: the second send got the first's folder). 109/109.
- Test(s):
- 2026-10-13 --
PresetStore.pathfinds a listed file whose name the sanitizer would rewrite (core_utils/presets/store.pyPresetStore.path).list()reports each file's own stem, so a shippedglTF 2.0.yamllisted asglTF 2.0, butpath()/source()/load()looked forglTF 2_0.yamland read it as missing. An existing file named exactly name (no path separator, and in the store: on Windows a drive-relativeD:eviljoined onto the store namedD:evil.yamlin that drive's current folder) now wins; any other name maps to its sanitized stem as before.- Test(s):
test_preset_store.pytest_a_listed_file_whose_name_sanitizes_differently_still_loads(red:source()None),test_a_drive_relative_name_never_leaves_the_store(Windows; red).
- Test(s):
- 2026-10-13 --
FileDependencies.search_dirsputs each file's own folder ahead of any folder holding a same-named twin (file_utils/file_dependencies.pyFileDependencies.search_dirs, new_unshadowed). A consumer that joins names onto the list binds the first folder holding the name, and the order was by reads alone: on a production room the texture root (105 readers) held a 512 px lightmap atlas from an earlier bake under the name (case aside) a current 2048 px one carried in its own folder (46 readers), so the FBX embedded and the GLB shipped the stale map through the current atlas rects -- blotchy, contact shadows gone (a bright strip at the base of every cabinet), the room 2x the level of the cabinets (Arnold-reference p90 error 77-88%; 7-17% with the right map). A folder that holds a file under a resolved dependency's name -- tested by the consumer's own join, so a case-folding file system folds case as it will -- without being that dependency's folder now follows its folder (a stable topological sort over the read order); two folders that shadow each other keep the read order and the names no order serves are warned. Each folder is listed once and only a name it holds is stated, not one probe per dependency per folder. The same scene carried a stray second carrier (data_export1, an older manifest naming a stale*_LightMap.exr), andFbxMedia.dependencies-- which keeps the FIRST spelling of a name, compared without case -- read carriers in file order, so a stray written ahead of the scene's own would have named the stale file for the embed; it now reads the scene's owndata_exportfirst, the GLB applier's precedence (fbx_media.py_FbxMediaInternal._channel_payloads).- Test(s):
test_file_dependencies.pynewtest_a_folder_holding_a_stale_twin_follows_the_maps_own_folder(red: the stale twin bound),test_twins_that_shadow_each_other_keep_the_read_order_and_warn(red: no warning),test_each_folder_is_listed_once_and_only_hits_are_stated(red: a probe per dependency per folder);test_fbx_media.pynewtest_the_scenes_own_carrier_names_a_file_before_any_other(red: the stray's spelling won),build_carrier_fbx(others=)writes further carriers ahead of the scene's own.
- Test(s):
- 2026-10-13 --
FbxMedia.merge_takesplays each take as it plays alone, between frames too (file_utils/mesh_convert/fbx_file.py_FbxFileInternal._union_curves,_interleave_curves, new_keep_own_tangents,_follows_on;fbx_media.pyFbxMedia.merge_takesdocstring). Maya writes spline, clamped and auto keys with zero slopes and its importer solves them from the neighbouring keys; merged, a take's last key and the next take's first gained each other as neighbours, so every edge segment changed shape (fresh mayapy, a Maya-written Shots Only file: up to 1.19 units off the take alone between frames, at a gap and at a seam). Each computed key whose neighbours the merge changed is now written as a user tangent carrying the slopes it plays in its own take (the left one in the previous key'sNextLeftSlope; broken where the sides differ): measured in the same fresh mayapy, every take within 1e-14 of itself alone over 420 quarter-frame samples.- Test(s):
test_fbx_media.pytest_each_take_plays_its_own_tangents_beside_a_boundary.
- Test(s):
- 2026-10-13 -- One temp root: every
TempArtifactsstore with nodirowns its own folder,<root>/<prefix>/, and a store's sweep can no longer reach another's entries (file_utils/temp_artifacts.pynewTempArtifacts.root,ROOT_ENV_VAR,STORE_MARKER,sweep_all,scoped,keep,managed,sweep_interval=,max_age_days=None;core_utils/test_sandbox.py). Stores sat flat in the system temp dir as<prefix>_<tag>and swept by prefix match, which is not nesting-safe: a scratch store<name>swept its own cache's<name>_cache_*entries by the scratch's 7 days (reproduced: a cache entry declared 30 days old went at 10), andblender_to_mtk/blender_to_mtk_tex,glb_pipeline/glb_pipeline_media,ptk_usdz/ptk_usdz_layeroverlapped the same way -- a cache's ownmax_age_dayswas never authoritative. Now the root is$PYTHONTK_TEMP_ROOT, else<tempfile.gettempdir()>/ptk, created on demand and spelled for the ANSI code page (AppLauncher.ansi_safe_path), so every payload minted there opens in Maya under a TEMP its code page cannot hold. Each store folder records the age its owner declared (.ptk_store.json), andTempArtifacts.sweep_all()-- run on its own at a process's first allocation when the root's last one is a day old -- reclaims a prefix that never allocates again by that age (an unreadable declaration reads as 30 days; a folder with none, and anything loose in the root, is never touched;Nonenever ages). The declaration is the LONGEST age any store of the folder declared (Nonethe longest), so a store spelled with a shorter default cannot age out a longer-lived one.TempArtifacts.contains(path)(new) answers whether a path is scratch it holds -- under the root, or for the legacy window the system temp dir -- resolved on both sides: the one spelling of mayatk's and blendertk's_in_tempand their Substance engine's_is_temp_path(check_temp_artifacts.pydrops the two_in_tempallowlist entries). A store's first allocation no longer scans the system temp dir: its own folder only, plus, for one release, a legacy sweep of its prefix's stale flat<temp>/<prefix>_*leftovers off one listing per process (removed in 0.16.0; a test fails once that window closes). Tags were the allocation clock alone, and Python 3.11's ~15 ms clock gave two processes one path (reproduced: one shareddir_path); an unnamed tag now carries the clock, the pid and a random part (<clock:016x><pid:x><rand:04x>; a session tag stays<clock>-<pid>), anddir_path()creates a minted folder exclusively, minting again over one that exists.keep(path)disowns the one result a scoped run must leave (thestage_dir = None+finally: rmtreeidiom);TempArtifacts.scoped(prefix)spells the scoped policy (the default stays"detached", documented as right only for a payload another process reads after you return).sweep_interval=lets a store built per call over a folder it does not own skip a rescan (atomic_write). A store with an explicitdirkeeps the flat<dir>/<prefix>_<tag>layout.TestSandbox.temp()setsPYTHONTK_TEMP_ROOTto its root (andPYTHONTK_CACHE_ROOTto a folder in it), so a store in a Python child lands in the sandbox however that child'stempfileresolves; a test that steers stores into its own folder patchesPYTHONTK_TEMP_ROOT, nottempfile.tempdir. Its top-level root sits flat in the temp root -- a root of roots, not a store folder: each nesting level is paid again by every path a suite builds inside it, and mayatk's scene-data records ran past Windows' 260 one level deeper (measured) -- and for one release it also reclaims the flat roots the old layout left in the system temp dir.- Test(s):
test_temp_artifacts.pynewTestRoot(3),TestStoreFolders(6; red:ca_cacheentry swept at 10 days by the 7-day scratch,glb_pipeline_mediaswept byglb_pipeline),TestLegacyFlatSweep(3),TestUniqueTags(3; red: one path for two pids in one tick, one shared folder),TestKeepAndScoped(3),TestSweepAll(4);test_the_marker_keeps_the_longest_age_any_alias_declared(red),test_contains_reads_the_root_and_the_legacy_temp_dir;test_default_dir_is_the_stores_own_folder_under_the_rootreplacestest_default_dir_is_system_temp;test_test_sandbox.pytest_the_temp_dir_is_one_throwaway_root_that_children_inherit(the root is the temp root), newtest_the_user_cache_is_inside_the_root_too,test_a_top_level_root_sits_flat_in_the_temp_root, the restore snapshot covers both new variables;test_execution_monitor.py,test_script_run.py,test_bridge.pysteer stores throughPYTHONTK_TEMP_ROOT. Suites: pythontk 7356 (7317 passed, 1 failed --test_preview_viewer_live's copy-report label, a load-timing flake that passes alone -- 38 skipped); uitk 5522 of 5531 (the 2 failures were tests another session rewrote mid-run; the 9 affected modules re-run 706/706); mayatk's 39 modules that use these primitives 3763/3763 (mtk_cfgconfig store flat in its sandbox, flat-path assertions intest_blender_bridge,test_scene_exporter,test_reference_managerand the sidecar assertion intest_emissive_groupsupdated); blendertk's 23 such suites 2723/2723 (test_reference_manager,test_emissive_groupslikewise).
- Test(s):
- 2026-10-13 --
CachedArtifact: the slot model is public, a slot can be a directory, scratch always lives under the temp root, and a project-resident cache never ages (file_utils/temp_artifacts.pynewCachedArtifact.slot,peek,touch,promote,cache_dir,directory=,max_age_days=None;core_utils/engines/textures/map_optimizer.pyMapOptimizer._encode_cache,_cached,_promote,_remember_kept). mayatk rebuilt the cache by hand from its private naming to answer "where is this key's bake" and "mark it in use" (_bake_slots,_bake_slot,_touch_bake), and MapOptimizer hand-rolled a directory-slot cache of its own (promote, read, touch, a.keptmarker written into the slot).slot(key)names a key's path without creating it,peek(key)answers only for a complete entry (a non-empty file, a directory that arrived by one rename),touch(key, sidecars=)restarts its age, andgetnow touches on every hit -- a hit wrote nothing, so a bake in daily use was swept at its age.directory=Truemakes each slot a folder (producefills an empty one);promote(key, produced)adopts what a batch produced itself, replacing a slot whole, across volumes by a copy beside the slot first. Scratch was created indir, beside the slots; it is always under the temp root now, and only the promoted result lands indir, soCachedArtifact(..., dir=ws.cache_dir("bake"), max_age_days=None)is a project cache a saved scene can reference. The cache store keeps its<name>_cacheprefix, soTempArtifacts(f"{name}_cache").path(name=key, extension=ext)-- mayatk's_bake_slotspelling -- still names the same slot. MapOptimizer's encode cache is a directory-slotCachedArtifact(map_optimizer, slots unchanged in name): an encode's scratch folder or a folder holding only the "kept" marker is promoted whole.- Test(s):
test_temp_artifacts.pynewTestCachedArtifactSlots(10, incl.test_the_spelling_mayatk_rebuilt_by_hand_still_names_the_slot,test_scratch_is_always_in_the_temp_root_never_the_cache_dir,test_a_project_resident_cache_is_never_age_swept,test_a_directory_slot_is_produced_whole_then_reused);test_map_optimizer.pynewtest_the_cache_is_the_shared_directory_slot_store,TestStageMapssteers its cache throughPYTHONTK_TEMP_ROOT.
- Test(s):
- 2026-10-13 --
UserConfig.cache_dir(*parts, create=False): the durable per-user cache root for regenerable caches that belong to no project;AppInstallerinstallslocation="cache"there, and"temp"is its retired spelling (core_utils/user_config.pynewcache_dir,CACHE_ROOT_ENV_VAR,xdg_home("cache");core_utils/app_installer.py). Resolved as the config root is:$PYTHONTK_CACHE_ROOT, else%LOCALAPPDATA%/pythontk/cache,~/Library/Caches/pythontk,$XDG_CACHE_HOME/pythontk(~/.cache/pythontk).location="temp"installed a downloaded tool into<system temp>/pythontk_tools, which the OS and every temp cleanup remove;"temp"now warns (Deprecation.values, remove in 0.16.0) and resolves to"cache".- Test(s):
test_user_config.pynewtest_the_cache_root_is_the_oss_own_cache_dir,test_the_cache_env_var_moves_it_and_parts_name_a_folder,test_xdg_home_takes_only_an_absolute_valuecoverscache;test_app_installer.pynewtest_resolve_location_cache_is_the_per_user_cache,test_resolve_location_temp_is_a_retired_spelling_of_cache(replacetest_resolve_location_temp).
- Test(s):
- 2026-10-13 --
Workspace.for_scene: one scene-to-project rule for both DCCs; and the permanent-file tree they share, resolved through rules (file_utils/workspace.pynewWorkspace.for_scene,cache_dir,movie_dir,images_dir,export_dir,backup_dir,relative,absolute). mayatk'sscene_project_root(the scene's own project, else the active workspace) and blendertk's (pin-aware) were two algorithms for one question.for_scene(scene, session_root): the scene's nearest marked ancestor, else the session root when it holds the scene, else the scene's own folder; an unsaved scene has the session root's workspace, or None -- never a temp fallback. The accessors use Maya's own rule names, so a Maya project stays a normal Maya project and a Blender project gets the same tree:cache_dir(kind)(rule<kind>Cache, elsecache/<kind>),movie_dir(movie/movies),images_dir,export_dir(FBX export,FBX, elsedata),backup_dir(scene)(Maya's<scene dir>/incrementalSave/<scene file>/);source_images_dirstays the one default for both (sourceimages, an existingtextures/matched). Asking writes nothing;create=Truemakes the folder.relative(path)spells a project file root-relative (POSIX) and anything outside absolute, never a../chain;absolute(stored)reads it back.- Test(s):
test_workspace.pynewWorkspaceForSceneTest(8),WorkspaceProjectStructureTest(6).
- Test(s):
- 2026-10-13 -- Nothing is written into the process's current directory, the drive root or a deliverable folder unasked (
img_utils/_channels.pyextract_channels;core_utils/engines/textures/map_factory/_converters.pyconvert_bump_to_normal,convert_normal_map_format,convert_spec_gloss_to_pbr;map_factory/processor.pysave_map;core_utils/logging_mixin/logger_ext.pyadd_file_handler;vid_utils/sequence_exporter.pySequenceExporter.export;core_utils/handoff/script_run.pyScriptRunner.run_script_to_artifact;core_utils/engines/textures/region_masks.pyRegionMaskPacker.writenewwrite_manifest=;net_utils/preview/_page_outputs.py). An in-memory image saved byextract_channelswith nooutput_dirwent to the cwd, and so did a PIL bump map'sbump_map_Normal_OpenGL.png: both raiseValueErrornow.convert_normal_map_formatof a bare file name wrote/<name>-- the drive root (reproduced:C:\mat_Normal_OpenGL.png); it writes beside the source.convert_spec_gloss_to_pbrresolvedoutput_dirand then wrote beside the specular map; it honours it. A dry run created the output folder; it creates nothing.add_file_handler()with no file wrotelogfile.loginto the cwd; it writes<logger name>.login the per-user cache'slogsfolder (UserConfig.cache_dir, resolved in the kernel: a temp store there was an upwardcore_utils -> file_utilsimport). A childScriptRunner.run_script_to_artifactlaunches with nocwdinherited the caller's, so a DCC's droppings (mayaDiskCache_*) landed wherever the caller was; it runs in a scratch folder of the run's own store, removed with the script (an explicitcwdwins). The encodes' PNG capture staged as<output>/<name>_png_tmpinside the deliverable folder; it is a scoped temp store (keep_frames=Truestill keeps the frames there, as an output), made only when an encode needs that capture.RegionMaskPacker.writereturns the manifest and writes the<mask>.jsonsidecar only on request (write_manifest=Trueormanifest_path=): no production code read it -- both DCCs publish the manifest through their scene records. The preview's page outputs (a still, a recording) asked whether the deliverable's folder was writable by creating a throwaway temp file in it; the still is now written there and falls back to the serve root on anOSError, and a recording is encoded in the serve root and delivered beside the deliverable (FileUtils.deliver_file), staying in the root where the folder takes no file.- Test(s):
test_img.pynewExtractChannelsCwdTest;test_map_factory.pynewtest_a_bump_image_with_no_path_names_no_folder_to_write,test_a_relative_normal_map_converts_beside_itself_not_at_the_drive_root,test_spec_gloss_writes_into_the_output_dir_it_was_given,test_a_dry_run_creates_no_output_folder;test_logging_mixin.pynewtest_a_file_handler_with_no_name_never_writes_into_the_cwd;test_sequence_exporter.pynewtest_intermediate_frames_never_land_in_the_deliverable_folder,test_no_scratch_folder_without_an_intermediate_capture(red);test_script_run.pynewTestWorkingDirectory(2; red: the caller's cwd);test_region_masks.pynewtest_write_writes_only_the_mask_by_default;test_preview_server.pynewtest_placing_a_still_writes_no_probe_into_the_users_folder,test_an_unwritable_deliverable_folder_falls_back_to_the_serve_rootsimulates the refused write;test_preview_playblast.pynewtest_a_folder_that_takes_no_file_leaves_the_movie_in_the_serve_root. All red before the fix.
- Test(s):
- 2026-10-13 --
AudioUtils: a transcode caches in the source's project (cache/audio) or the per-user cache, never beside the source, and a failed conversion can no longer poison the cache (audio_utils/_audio_utils.pynewAudioUtils.cache_dir_for;ensure_playable_path,resolve_playable_path,build_audio_map). The default cache was<source dir>/_audio_cache/, a folder written into the user's audio folder.cache_dir_for(source)is the one place it is decided: a source in a marked workspace caches inWorkspace.cache_dir("audio")(the scene that plays it references the WAV, so it travels with the project), any other inUserConfig.cache_dir("audio"). ffmpeg wrote straight to the cache name and a cached file was returned unchecked, so a failed or killed run left a partial<stem>_<md5>.wavthe next call returned (reproduced). The transcode now goes throughFileUtils.atomic_write(-f wavinto the.part), and a cached file is reused only when its RIFF size matches the file -- checked before ffmpeg is looked up, so a cached transcode plays on a machine without it.- Test(s):
test_audio_utils.pynewTestPlayableCache(6; red: nocache_dir_for, the partial served as the cache, ffmpeg required for a cache hit).
- Test(s):
- 2026-10-13 --
FileUtils.atomic_write_textisatomic_writewith a text writer, so a temp a killed write left is swept;ImgUtils.cv2_temppoints OpenCV at the temp root (file_utils/_file_utils.py;img_utils/_codecs.py;m3trik/scripts/check_temp_artifacts.pydrops its allowlist entry). The hand-rolled.<uuid>.tmpbeside the target was never removed by anything once a process died mid-write; it is anatomic_writetemp now, swept once stale by a later write into the folder, at most once per folder every ten minutes in a process (a batch of sidecars no longer rescans per file).atomic_write's temp is.atomic_<12 hex>.part: a dot name (hidden, skipped by every listing that skips dot files, as the old temp was) and short -- the temp spends the target folder's path budget, and a 43-character store tag put a 258-character record's temp past Windows' 260 (measured).cv2_tempswappedTEMP/TMPfor the short spelling of the system temp dir through a second copy of theGetShortPathNameWcall; it names an ASCII spelling of a folder of the temp root (TempArtifacts("cv2_temp")) through the one short-name helper (AppLauncher.ansi_safe_path), still scoped and shared by overlapping blocks, so what a crashed codec leaves is swept.FileUtils.copy_fileremoved the target and then copied onto its name, so a failed copy left nothing (or a truncated file); it copies throughatomic_write, and the three hand-spelledatomic_write(dst, copyfile)sites call it (FileUtils.deliver_file,CachedArtifact's cross-volume promotion,Fbx2Gltf's GLB delivery: data and metadata now, ascopy2).- Test(s):
test_atomic_write.pynewtest_a_stale_temp_a_killed_write_left_is_swept_by_a_later_write,test_the_temp_is_hidden_and_no_longer_than_a_short_name(red);test_img.pytest_overlapping_blocks_share_one_swappins the target under the root (red);test_file_transfer.pynewtest_a_failed_copy_leaves_the_existing_file_whole(red).
- Test(s):