prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [shar] cut can't load feature
  when use
  shards = train_cuts.to_shar(data_dir, fields={"features": "lilcom"}, shard_size=2000, num_jobs=20)
  to make shar packages ;
  
  one cut like:
  MonoCut(id='X0000013171_273376986_S00164_sp1.1', start=0, duration=2.4818125, channel=0, supervisions=[SupervisionSegment(id='X0000013171_273376986_S00164_sp1.1', recording_id='X0000013171_273376986_sp1.1', start=0.0, duration=2.4818125, channel=0, text='用/花/里/胡/哨/的/甜/言/蜜/语/维/持/的/婚/姻', language='Chinese', speaker=None, gender=None, custom=None, alignment=None)], features=Features(type='kaldifeat-fbank', num_frames=248, num_features=80, frame_shift=0.01, sampling_rate=16000, start=425.6818125, duration=2.4818125, storage_type='memory_lilcom', storage_path='', storage_key='<binary-data>', recording_id='X0000013171_273376986_sp1.1', channels=0), recording=Recording(id='X0000013171_273376986_sp1.1', sources=[AudioSource(type='file', channels=[0], source='/store52/audio_data/WenetSpeech/audio/audio/train/podcast/B00051/X0000013171_273376986.opus')], sampling_rate=16000, num_samples=10926255, duration=682.8909375, channel_ids=[0], transforms=[{'name': 'Speed', 'kwargs': {'factor': 1.1}}]), custom={'dataloading_info': {'rank': 0, 'world_size': 1, 'worker_id': None}, 'shard_origin': PosixPath('cuts.020360.jsonl.gz'), 'shar_epoch': 0})
  
  then try to load features :
  cut.load_features()
  
  has ERROR:
   ValueError: Cannot load features for recording X0000013171_273376986_sp1.1 starting from 0s. The available range is (425.6818125, 428.16362499999997) seconds.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lhotse/shar/utils.py`
  Content:
  ```
  1 from pathlib import Path
  2 from typing import Optional, TypeVar, Union
  3 
  4 from lhotse import AudioSource, Features, Recording, compute_num_samples, fastcopy
  5 from lhotse.array import Array, TemporalArray
  6 from lhotse.cut import Cut
  7 from lhotse.utils import Pathlike
  8 
  9 Manifest = TypeVar("Manifest", Recording, Features, Array, TemporalArray)
  10 
  11 
  12 def to_shar_placeholder(manifest: Manifest, cut: Optional[Cut] = None) -> Manifest:
  13     if isinstance(manifest, Recording):
  14         kwargs = (
  15             {}
  16             if cut is None
  17             else dict(
  18                 duration=cut.duration,
  19                 num_samples=compute_num_samples(cut.duration, manifest.sampling_rate),
  20             )
  21         )
  22         return fastcopy(
  23             manifest,
  24             # Creates a single AudioSource out of multiple ones.
  25             sources=[
  26                 AudioSource(type="shar", channels=manifest.channel_ids, source="")
  27             ],
  28             # Removes the transform metadata because they were already executed.
  29             transforms=None,
  30             **kwargs,
  31         )
  32     # TODO: modify Features/TemporalArray's start/duration/num_frames if needed to match the Cut (in case we read subset of array)
  33     elif isinstance(manifest, (Array, Features)):
  34         return fastcopy(manifest, storage_type="shar", storage_path="", storage_key="")
  35     elif isinstance(manifest, TemporalArray):
  36         return fastcopy(
  37             manifest,
  38             array=fastcopy(
  39                 manifest.array, storage_type="shar", storage_path="", storage_key=""
  40             ),
  41         )
  42 
  43 
  44 def fill_shar_placeholder(
  45     manifest: Union[Cut, Recording, Features, Array, TemporalArray],
  46     data: bytes,
  47     tarpath: Pathlike,
  48     field: Optional[str] = None,
  49 ) -> None:
  50     if isinstance(manifest, Cut):
  51         assert (
  52             field is not None
  53         ), "'field' argument must be provided when filling a Shar placeholder in a Cut."
  54         manifest = getattr(manifest, field)
  55         fill_shar_placeholder(
  56             manifest=manifest, field=field, data=data, tarpath=tarpath
  57         )
  58 
  59     tarpath = Path(tarpath)
  60 
  61     if isinstance(manifest, Recording):
  62         assert (
  63             len(manifest.sources) == 1
  64         ), "We expected a single (possibly multi-channel) AudioSource in Shar format."
  65         manifest.sources[0].type = "memory"
  66         manifest.sources[0].source = data
  67 
  68     elif isinstance(manifest, (Features, Array)):
  69         manifest.storage_key = data
  70         if tarpath.suffix == ".llc":
  71             manifest.storage_type = "memory_lilcom"
  72         elif tarpath.suffix == ".npy":
  73             manifest.storage_type = "memory_npy"
  74         else:
  75             raise RuntimeError(f"Unknown array/tensor format: {tarpath}")
  76 
  77     elif isinstance(manifest, TemporalArray):
  78         manifest.array.storage_key = data
  79         if tarpath.suffix == ".llc":
  80             manifest.array.storage_type = "memory_lilcom"
  81         elif tarpath.suffix == ".npy":
  82             manifest.array.storage_type = "memory_npy"
  83         else:
  84             raise RuntimeError(f"Unknown array/tensor format: {tarpath}")
  85 
  86     else:
  87         raise RuntimeError(f"Unknown manifest type: {type(manifest).__name__}")
  88
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lhotse/shar/utils.py b/lhotse/shar/utils.py
  --- a/lhotse/shar/utils.py
  +++ b/lhotse/shar/utils.py
  @@ -11,14 +11,6 @@
   
   def to_shar_placeholder(manifest: Manifest, cut: Optional[Cut] = None) -> Manifest:
       if isinstance(manifest, Recording):
  -        kwargs = (
  -            {}
  -            if cut is None
  -            else dict(
  -                duration=cut.duration,
  -                num_samples=compute_num_samples(cut.duration, manifest.sampling_rate),
  -            )
  -        )
           return fastcopy(
               manifest,
               # Creates a single AudioSource out of multiple ones.
  @@ -27,18 +19,35 @@
               ],
               # Removes the transform metadata because they were already executed.
               transforms=None,
  -            **kwargs,
  +            duration=cut.duration if cut is not None else manifest.duration,
  +            num_samples=compute_num_samples(cut.duration, manifest.sampling_rate)
  +            if cut is not None
  +            else manifest.num_samples,
           )
  -    # TODO: modify Features/TemporalArray's start/duration/num_frames if needed to match the Cut (in case we read subset of array)
  -    elif isinstance(manifest, (Array, Features)):
  +    elif isinstance(manifest, Array):
           return fastcopy(manifest, storage_type="shar", storage_path="", storage_key="")
  +    elif isinstance(manifest, Features):
  +        return fastcopy(
  +            manifest,
  +            start=0,
  +            duration=cut.duration if cut is not None else manifest.duration,
  +            storage_type="shar",
  +            storage_path="",
  +            storage_key="",
  +        )
       elif isinstance(manifest, TemporalArray):
           return fastcopy(
               manifest,
  +            start=0,
               array=fastcopy(
  -                manifest.array, storage_type="shar", storage_path="", storage_key=""
  +                manifest.array,
  +                storage_type="shar",
  +                storage_path="",
  +                storage_key="",
               ),
           )
  +    else:
  +        raise RuntimeError(f"Unexpected manifest type: {type(manifest)}")
   
   
   def fill_shar_placeholder(
  
verification_info: {"golden_diff": "diff --git a/lhotse/shar/utils.py b/lhotse/shar/utils.py\n--- a/lhotse/shar/utils.py\n+++ b/lhotse/shar/utils.py\n@@ -11,14 +11,6 @@\n \n def to_shar_placeholder(manifest: Manifest, cut: Optional[Cut] = None) -> Manifest:\n     if isinstance(manifest, Recording):\n-        kwargs = (\n-            {}\n-            if cut is None\n-            else dict(\n-                duration=cut.duration,\n-                num_samples=compute_num_samples(cut.duration, manifest.sampling_rate),\n-            )\n-        )\n         return fastcopy(\n             manifest,\n             # Creates a single AudioSource out of multiple ones.\n@@ -27,18 +19,35 @@\n             ],\n             # Removes the transform metadata because they were already executed.\n             transforms=None,\n-            **kwargs,\n+            duration=cut.duration if cut is not None else manifest.duration,\n+            num_samples=compute_num_samples(cut.duration, manifest.sampling_rate)\n+            if cut is not None\n+            else manifest.num_samples,\n         )\n-    # TODO: modify Features/TemporalArray's start/duration/num_frames if needed to match the Cut (in case we read subset of array)\n-    elif isinstance(manifest, (Array, Features)):\n+    elif isinstance(manifest, Array):\n         return fastcopy(manifest, storage_type=\"shar\", storage_path=\"\", storage_key=\"\")\n+    elif isinstance(manifest, Features):\n+        return fastcopy(\n+            manifest,\n+            start=0,\n+            duration=cut.duration if cut is not None else manifest.duration,\n+            storage_type=\"shar\",\n+            storage_path=\"\",\n+            storage_key=\"\",\n+        )\n     elif isinstance(manifest, TemporalArray):\n         return fastcopy(\n             manifest,\n+            start=0,\n             array=fastcopy(\n-                manifest.array, storage_type=\"shar\", storage_path=\"\", storage_key=\"\"\n+                manifest.array,\n+                storage_type=\"shar\",\n+                storage_path=\"\",\n+                storage_key=\"\",\n             ),\n         )\n+    else:\n+        raise RuntimeError(f\"Unexpected manifest type: {type(manifest)}\")\n \n \n def fill_shar_placeholder(\n", "issue": "[shar] cut can't load feature\nwhen use\r\nshards = train_cuts.to_shar(data_dir, fields={\"features\": \"lilcom\"}, shard_size=2000, num_jobs=20)\r\nto make shar packages ;\r\n\r\none cut like:\r\nMonoCut(id='X0000013171_273376986_S00164_sp1.1', start=0, duration=2.4818125, channel=0, supervisions=[SupervisionSegment(id='X0000013171_273376986_S00164_sp1.1', recording_id='X0000013171_273376986_sp1.1', start=0.0, duration=2.4818125, channel=0, text='\u7528/\u82b1/\u91cc/\u80e1/\u54e8/\u7684/\u751c/\u8a00/\u871c/\u8bed/\u7ef4/\u6301/\u7684/\u5a5a/\u59fb', language='Chinese', speaker=None, gender=None, custom=None, alignment=None)], features=Features(type='kaldifeat-fbank', num_frames=248, num_features=80, frame_shift=0.01, sampling_rate=16000, start=425.6818125, duration=2.4818125, storage_type='memory_lilcom', storage_path='', storage_key='<binary-data>', recording_id='X0000013171_273376986_sp1.1', channels=0), recording=Recording(id='X0000013171_273376986_sp1.1', sources=[AudioSource(type='file', channels=[0], source='/store52/audio_data/WenetSpeech/audio/audio/train/podcast/B00051/X0000013171_273376986.opus')], sampling_rate=16000, num_samples=10926255, duration=682.8909375, channel_ids=[0], transforms=[{'name': 'Speed', 'kwargs': {'factor': 1.1}}]), custom={'dataloading_info': {'rank': 0, 'world_size': 1, 'worker_id': None}, 'shard_origin': PosixPath('cuts.020360.jsonl.gz'), 'shar_epoch': 0})\r\n\r\nthen try to load features :\r\ncut.load_features()\r\n\r\nhas ERROR:\r\n ValueError: Cannot load features for recording X0000013171_273376986_sp1.1 starting from 0s. The available range is (425.6818125, 428.16362499999997) seconds.\n", "before_files": [{"content": "from pathlib import Path\nfrom typing import Optional, TypeVar, Union\n\nfrom lhotse import AudioSource, Features, Recording, compute_num_samples, fastcopy\nfrom lhotse.array import Array, TemporalArray\nfrom lhotse.cut import Cut\nfrom lhotse.utils import Pathlike\n\nManifest = TypeVar(\"Manifest\", Recording, Features, Array, TemporalArray)\n\n\ndef to_shar_placeholder(manifest: Manifest, cut: Optional[Cut] = None) -> Manifest:\n    if isinstance(manifest, Recording):\n        kwargs = (\n            {}\n            if cut is None\n            else dict(\n                duration=cut.duration,\n                num_samples=compute_num_samples(cut.duration, manifest.sampling_rate),\n            )\n        )\n        return fastcopy(\n            manifest,\n            # Creates a single AudioSource out of multiple ones.\n            sources=[\n                AudioSource(type=\"shar\", channels=manifest.channel_ids, source=\"\")\n            ],\n            # Removes the transform metadata because they were already executed.\n            transforms=None,\n            **kwargs,\n        )\n    # TODO: modify Features/TemporalArray's start/duration/num_frames if needed to match the Cut (in case we read subset of array)\n    elif isinstance(manifest, (Array, Features)):\n        return fastcopy(manifest, storage_type=\"shar\", storage_path=\"\", storage_key=\"\")\n    elif isinstance(manifest, TemporalArray):\n        return fastcopy(\n            manifest,\n            array=fastcopy(\n                manifest.array, storage_type=\"shar\", storage_path=\"\", storage_key=\"\"\n            ),\n        )\n\n\ndef fill_shar_placeholder(\n    manifest: Union[Cut, Recording, Features, Array, TemporalArray],\n    data: bytes,\n    tarpath: Pathlike,\n    field: Optional[str] = None,\n) -> None:\n    if isinstance(manifest, Cut):\n        assert (\n            field is not None\n        ), \"'field' argument must be provided when filling a Shar placeholder in a Cut.\"\n        manifest = getattr(manifest, field)\n        fill_shar_placeholder(\n            manifest=manifest, field=field, data=data, tarpath=tarpath\n        )\n\n    tarpath = Path(tarpath)\n\n    if isinstance(manifest, Recording):\n        assert (\n            len(manifest.sources) == 1\n        ), \"We expected a single (possibly multi-channel) AudioSource in Shar format.\"\n        manifest.sources[0].type = \"memory\"\n        manifest.sources[0].source = data\n\n    elif isinstance(manifest, (Features, Array)):\n        manifest.storage_key = data\n        if tarpath.suffix == \".llc\":\n            manifest.storage_type = \"memory_lilcom\"\n        elif tarpath.suffix == \".npy\":\n            manifest.storage_type = \"memory_npy\"\n        else:\n            raise RuntimeError(f\"Unknown array/tensor format: {tarpath}\")\n\n    elif isinstance(manifest, TemporalArray):\n        manifest.array.storage_key = data\n        if tarpath.suffix == \".llc\":\n            manifest.array.storage_type = \"memory_lilcom\"\n        elif tarpath.suffix == \".npy\":\n            manifest.array.storage_type = \"memory_npy\"\n        else:\n            raise RuntimeError(f\"Unknown array/tensor format: {tarpath}\")\n\n    else:\n        raise RuntimeError(f\"Unknown manifest type: {type(manifest).__name__}\")\n", "path": "lhotse/shar/utils.py"}], "after_files": [{"content": "from pathlib import Path\nfrom typing import Optional, TypeVar, Union\n\nfrom lhotse import AudioSource, Features, Recording, compute_num_samples, fastcopy\nfrom lhotse.array import Array, TemporalArray\nfrom lhotse.cut import Cut\nfrom lhotse.utils import Pathlike\n\nManifest = TypeVar(\"Manifest\", Recording, Features, Array, TemporalArray)\n\n\ndef to_shar_placeholder(manifest: Manifest, cut: Optional[Cut] = None) -> Manifest:\n    if isinstance(manifest, Recording):\n        return fastcopy(\n            manifest,\n            # Creates a single AudioSource out of multiple ones.\n            sources=[\n                AudioSource(type=\"shar\", channels=manifest.channel_ids, source=\"\")\n            ],\n            # Removes the transform metadata because they were already executed.\n            transforms=None,\n            duration=cut.duration if cut is not None else manifest.duration,\n            num_samples=compute_num_samples(cut.duration, manifest.sampling_rate)\n            if cut is not None\n            else manifest.num_samples,\n        )\n    elif isinstance(manifest, Array):\n        return fastcopy(manifest, storage_type=\"shar\", storage_path=\"\", storage_key=\"\")\n    elif isinstance(manifest, Features):\n        return fastcopy(\n            manifest,\n            start=0,\n            duration=cut.duration if cut is not None else manifest.duration,\n            storage_type=\"shar\",\n            storage_path=\"\",\n            storage_key=\"\",\n        )\n    elif isinstance(manifest, TemporalArray):\n        return fastcopy(\n            manifest,\n            start=0,\n            array=fastcopy(\n                manifest.array,\n                storage_type=\"shar\",\n                storage_path=\"\",\n                storage_key=\"\",\n            ),\n        )\n    else:\n        raise RuntimeError(f\"Unexpected manifest type: {type(manifest)}\")\n\n\ndef fill_shar_placeholder(\n    manifest: Union[Cut, Recording, Features, Array, TemporalArray],\n    data: bytes,\n    tarpath: Pathlike,\n    field: Optional[str] = None,\n) -> None:\n    if isinstance(manifest, Cut):\n        assert (\n            field is not None\n        ), \"'field' argument must be provided when filling a Shar placeholder in a Cut.\"\n        manifest = getattr(manifest, field)\n        fill_shar_placeholder(\n            manifest=manifest, field=field, data=data, tarpath=tarpath\n        )\n\n    tarpath = Path(tarpath)\n\n    if isinstance(manifest, Recording):\n        assert (\n            len(manifest.sources) == 1\n        ), \"We expected a single (possibly multi-channel) AudioSource in Shar format.\"\n        manifest.sources[0].type = \"memory\"\n        manifest.sources[0].source = data\n\n    elif isinstance(manifest, (Features, Array)):\n        manifest.storage_key = data\n        if tarpath.suffix == \".llc\":\n            manifest.storage_type = \"memory_lilcom\"\n        elif tarpath.suffix == \".npy\":\n            manifest.storage_type = \"memory_npy\"\n        else:\n            raise RuntimeError(f\"Unknown array/tensor format: {tarpath}\")\n\n    elif isinstance(manifest, TemporalArray):\n        manifest.array.storage_key = data\n        if tarpath.suffix == \".llc\":\n            manifest.array.storage_type = \"memory_lilcom\"\n        elif tarpath.suffix == \".npy\":\n            manifest.array.storage_type = \"memory_npy\"\n        else:\n            raise RuntimeError(f\"Unknown array/tensor format: {tarpath}\")\n\n    else:\n        raise RuntimeError(f\"Unknown manifest type: {type(manifest).__name__}\")\n", "path": "lhotse/shar/utils.py"}]}