nebius/SWE-bench-extra huggingface dataset:
Repository: just-work/fffw

Issue:
Trim sets incorrect duration
If Trim end is after EOF, stream output duration is greater than expected.

Comments:

Patch:
diff --git a/fffw/encoding/filters.py b/fffw/encoding/filters.py
index 194424c..1f49262 100644
--- a/fffw/encoding/filters.py
+++ b/fffw/encoding/filters.py
@@ -261,6 +261,8 @@ class Trim(AutoFilter):
         meta = metadata[0]
         scenes = []
         streams: List[str] = []
+        start = self.start or TS(0)
+        end = min(meta.duration, self.end or TS(0))
         for scene in meta.scenes:
             if scene.stream and (not streams or streams[0] != scene.stream):
                 # Adding an input stream without contiguous duplicates.
@@ -279,12 +281,12 @@ class Trim(AutoFilter):
                                     duration=end - start))
 
         kwargs = {
-            'start': self.start,
-            'duration': self.end,
+            'start': start,
+            'duration': end,
             'scenes': scenes,
             'streams': streams
         }
-        interval = cast(TS, self.end) - cast(TS, self.start)
+        interval = cast(TS, end) - cast(TS, start)
         if isinstance(meta, AudioMeta):
             kwargs['samples'] = round(meta.sampling_rate * interval)
         if isinstance(meta, VideoMeta):


Test patch:
diff --git a/tests/test_graph.py b/tests/test_graph.py
index ecf7948..c7db0fd 100644
--- a/tests/test_graph.py
+++ b/tests/test_graph.py
@@ -316,6 +316,15 @@ class FilterGraphTestCase(TestCase):
         self.assertEqual(vm.duration, TS(4.0))
         self.assertEqual(vm.frames, 1.0 * vm.frame_rate)
 
+    def test_video_trim_end_of_stream(self):
+        """
+        If Trim ends after stream end, duration is set to min value.
+        """
+        f = self.source | Trim(VIDEO, start=5.0, end=400.0) | SetPTS(VIDEO)
+        f > self.output
+        vm = cast(VideoMeta, self.output.codecs[0].get_meta_data())
+        self.assertEqual(vm.duration, TS(295.0))
+
     def test_audio_trim_metadata(self):
         """
         Trim filter sets start and changes stream duration.
Repository: just-work/fffw

Issue:
Wrong MKV duration
In MKV container duration field contains float milliseconds value and in MP4 container it's int.
TS implementation parses int as milliseconds and float as seconds (because of ffmpeg duration meanings).

media info normalizer should perform duration rounding.

Comments:

Patch:
diff --git a/fffw/graph/meta.py b/fffw/graph/meta.py
index 5ed0f15..328d1f0 100644
--- a/fffw/graph/meta.py
+++ b/fffw/graph/meta.py
@@ -381,9 +381,28 @@ class AudioMeta(Meta):
         assert abs(self.samples - interval * self.sampling_rate) <= 1
 
 
+def maybe_parse_duration(value: Union[str, float, int, None]) -> TS:
+    """
+    Parses duration from mediainfo output, if necessary.
+
+    Some containers store float value and some int, but in both cases (which is different from ffmpeg) value is
+    counted in milliseconds.
+    """
+    if value is None:
+        return TS(0)
+    if isinstance(value, str):
+        try:
+            value = int(value)
+        except ValueError:
+            # prepare seconds for TS constructor
+            value = float(value) / 1000
+    return TS(value)
+
+
 def audio_meta_data(**kwargs: Any) -> AudioMeta:
+    duration = maybe_parse_duration(kwargs.get('duration'))
+
     stream = kwargs.get('stream')
-    duration = TS(kwargs.get('duration', 0))
     start = TS(kwargs.get('start', 0))
     scene = Scene(
         stream=stream,
@@ -405,7 +424,7 @@ def audio_meta_data(**kwargs: Any) -> AudioMeta:
 
 
 def video_meta_data(**kwargs: Any) -> VideoMeta:
-    duration = TS(kwargs.get('duration', 0))
+    duration = maybe_parse_duration(kwargs.get('duration'))
     width = int(kwargs.get('width', 0))
     height = int(kwargs.get('height', 0))
     par = float(kwargs.get('pixel_aspect_ratio', 1.0))


Test patch:
diff --git a/tests/test_meta_data.py b/tests/test_meta_data.py
index d8fed7f..6ad882b 100644
--- a/tests/test_meta_data.py
+++ b/tests/test_meta_data.py
@@ -2,9 +2,10 @@ import json
 from copy import deepcopy
 from dataclasses import dataclass, fields
 from datetime import timedelta
+from itertools import product
 from typing import Iterable, Tuple, Any
 from unittest import TestCase
-from itertools import product
+
 from pymediainfo import MediaInfo  # type: ignore
 
 from fffw.graph import meta
@@ -268,6 +269,17 @@ class MetaDataTestCase(TestCase):
 
         self.assertTrue(fields(ExtendedVideoMeta))
 
+    def test_mkv_stream_duration(self):
+        """ MKV duration is stored as float and this is a problem for TS constuctor."""
+        original = meta.from_media_info(self.media_info)
+        s = SAMPLE
+        s = s.replace('<Duration>6742</Duration>', '<Duration>6742.000000</Duration>')
+        s = s.replace('<Duration>6740</Duration>', '<Duration>6740.000000</Duration>')
+        streams = meta.from_media_info(MediaInfo(s))
+        self.assertEqual(len(original), len(streams))
+        for s, o in zip(streams, original):
+            self.assertEqual(s.duration, o.duration)
+
 
 class TimeStampTestCase(TestCase):
     td: timedelta
Repository: just-work/fffw

Issue:
FFMPEG.add_output shortcuts imisbehaving
```
output = ff > output_file('output.mp4', VideoCodec('libx264'))

stream > output
```
The code above does not work because second line raises "no free codecs" error.

Relates to #43

Comments:

Patch:
diff --git a/examples/overlay.py b/examples/overlay.py
index 800fa90..a7926c7 100644
--- a/examples/overlay.py
+++ b/examples/overlay.py
@@ -11,7 +11,7 @@ overlay = ff.video | Overlay(x=1720, y=100)
 # scale logo to 100x100 and pass as top layer to overlay filter
 logo | Scale(width=100, height=100) | overlay
 
-# tell ffmpeg that it'll output something to destination file
-output = ff > output_file('output.mp4')
 # output video with logo to destination file
-overlay > output
+output = overlay > output_file('output.mp4', VideoCodec('libx264'))
+# tell ffmpeg that it'll output something to destination file
+ff > output
diff --git a/fffw/encoding/outputs.py b/fffw/encoding/outputs.py
index 267c59d..4d0e471 100644
--- a/fffw/encoding/outputs.py
+++ b/fffw/encoding/outputs.py
@@ -110,7 +110,7 @@ class Output(BaseWrapper):
     format: str = param(name="f")
     output_file: str = param(name="", skip=True)
 
-    def __lt__(self, other: base.InputType) -> Codec:
+    def __lt__(self, other: base.InputType) -> "Output":
         """
         Connects a source or a filter to a first free codec.
 
@@ -118,7 +118,7 @@ class Output(BaseWrapper):
         """
         codec = self.get_free_codec(other.kind)
         other.connect_dest(codec)
-        return codec
+        return self
 
     @property
     def video(self) -> Codec:


Test patch:
diff --git a/tests/test_ffmpeg.py b/tests/test_ffmpeg.py
index dcb2105..10e52e3 100644
--- a/tests/test_ffmpeg.py
+++ b/tests/test_ffmpeg.py
@@ -493,3 +493,19 @@ class FFMPEGTestCase(BaseTestCase):
         ff > output
 
         ff.check_buffering()
+
+    def test_shortcut_outputs_with_codec(self):
+        """ Check ff > output shortcut if codecs list specified."""
+        ff = FFMPEG(input=inputs.input_file("input.mp4"))
+        scaled = ff.video | filters.Scale(width=1280, height=720)
+
+        with self.assertRaises(RuntimeError):
+            codec = codecs.VideoCodec("libx264")
+            out = ff > outputs.output_file("output.mp4", codec)
+            # at this moment codec is connected to ffmpeg input stream directly
+            # so scaled video stream could not be connected to output
+            scaled > out
+
+        codec = codecs.VideoCodec("libx264")
+        out = scaled > outputs.output_file("output.mp4", codec)
+        ff > out
Repository: just-work/fffw

Issue:
Filter with skipped params could not be cloned
`TypeError: __init__() got an unexpected keyword argument 'extra_hw_frames'`


Comments:

Patch:
diff --git a/fffw/encoding/filters.py b/fffw/encoding/filters.py
index bd06ae6..ff1baa2 100644
--- a/fffw/encoding/filters.py
+++ b/fffw/encoding/filters.py
@@ -1,4 +1,4 @@
-from dataclasses import dataclass, replace, asdict, field
+from dataclasses import dataclass, replace, asdict, field, fields
 from typing import Union, List, cast
 
 from fffw.graph import base
@@ -91,7 +91,8 @@ class Filter(mixins.StreamValidationMixin, base.Node, Params):
 
         Inputs and outputs are not copied.
         """
-        kwargs = asdict(self)
+        skip = [f.name for f in fields(self) if not f.init]
+        kwargs = {k: v for k, v in asdict(self).items() if k not in skip}
         # noinspection PyArgumentList
         return type(self)(**kwargs)  # type: ignore
 


Test patch:
diff --git a/tests/test_vector.py b/tests/test_vector.py
index 50794cd..bc4e8c8 100644
--- a/tests/test_vector.py
+++ b/tests/test_vector.py
@@ -1,4 +1,4 @@
-from dataclasses import dataclass, replace
+from dataclasses import dataclass, replace, asdict
 from typing import cast, Tuple
 
 from fffw.encoding import *
@@ -373,3 +373,17 @@ class VectorTestCase(BaseTestCase):
             '-c:a', 'libfdk_aac',
             'output2.mp5'
         )
+
+    def test_clone_filter_with_skipped_params(self):
+        """
+        A filter with `init=False` param is cloned correctly.
+        """
+        @dataclass
+        class MyFilter(filters.VideoFilter):
+            my_flag: bool = param(init=False, default=True)
+
+        f = MyFilter()
+
+        cloned = f._clone()
+
+        self.assertTrue(asdict(cloned)['my_flag'])
Repository: just-work/fffw

Issue:
Split and concat should validate against any hardware
splitting and concatenation is supported in every hardware acceleration

Comments:

Patch:
diff --git a/fffw/encoding/filters.py b/fffw/encoding/filters.py
index 1ef1505..43ed444 100644
--- a/fffw/encoding/filters.py
+++ b/fffw/encoding/filters.py
@@ -202,6 +202,10 @@ class Split(AutoFilter):
             return ''
         return str(self.output_count)
 
+    def validate_edge_device(self, edge: base.Edge) -> None:
+        # Any device is supported
+        return
+
 
 @dataclass
 class Trim(AutoFilter):
@@ -351,6 +355,10 @@ class Concat(Filter):
             kwargs['samples'] = samples
         return replace(metadata[0], **kwargs)
 
+    def validate_edge_device(self, edge: base.Edge) -> None:
+        # Any device is supported
+        return
+
 
 @dataclass
 class Overlay(VideoFilter):


Test patch:
diff --git a/tests/test_graph.py b/tests/test_graph.py
index 905464c..6b9bb4c 100644
--- a/tests/test_graph.py
+++ b/tests/test_graph.py
@@ -305,3 +305,17 @@ class FilterGraphTestCase(TestCase):
 
         cuda = meta.Device(hardware='cuda', name='foo')
         self.source.video | Upload(device=cuda) | ScaleCuda(640, 360)
+
+    def test_concat_split_allows_any_hardware(self):
+        """
+        Concat and split filters allow any hardware acceleration.
+        """
+        try:
+            cuda = meta.Device(hardware='cuda', name='foo')
+            hw = self.source.video | Upload(device=cuda)
+            split = hw | Split(VIDEO, output_count=2)
+            concat = Concat(VIDEO, input_count=2)
+            split | concat
+            split | concat
+        except ValueError:  # pragma: no cover
+            self.fail("hardware validation unexpectedly failed")
Repository: just-work/fffw

Issue:
Incorrect as_pairs behavior if default is not set
```python
  File "/data/encoder/virtualenv/lib/python3.6/site-packages/fffw/wrapper/params.py", line 92, in as_pairs
    if f.default == value and f.init:
  File "/data/encoder/virtualenv/lib/python3.6/site-packages/fffw/graph/meta.py", line 104, in wrapper
    return cast(BinaryOp, func)(self, TS(value))  # noqa
  File "/data/encoder/virtualenv/lib/python3.6/site-packages/fffw/graph/meta.py", line 144, in __new__
    return super().__new__(cls, value)  # type: ignore
TypeError: float() argument must be a string or a number, not '_MISSING_TYPE'
```

There should be a MISSING check


Comments:

Patch:
diff --git a/fffw/wrapper/params.py b/fffw/wrapper/params.py
index 11dc74a..a509f88 100644
--- a/fffw/wrapper/params.py
+++ b/fffw/wrapper/params.py
@@ -1,4 +1,4 @@
-from dataclasses import field, dataclass, Field, fields
+from dataclasses import field, dataclass, Field, fields, MISSING
 from typing import Any, Optional, Tuple, cast, List, Callable
 
 
@@ -89,7 +89,7 @@ class Params:
         for f in self._fields:  # type: Field
             key = f.name
             value = getattr(self, key)
-            if f.default == value and f.init:
+            if f.default is not MISSING and f.default == value and f.init:
                 # if field value has default value and is configurable via
                 # __init__, we omit this field
                 continue


Test patch:
diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py
index ba68852..d6e4ea4 100644
--- a/tests/test_wrapper.py
+++ b/tests/test_wrapper.py
@@ -7,8 +7,10 @@ from dataclasses import dataclass
 from typing import List
 from unittest import TestCase, mock
 
+from fffw.graph import TS
 from fffw.wrapper import param
 from fffw.wrapper.base import UniversalLineReader, BaseWrapper
+from fffw.wrapper.params import Params
 
 
 @dataclass
@@ -119,3 +121,20 @@ class UniversalLineReaderTestCase(TestCase):
 
         with self.assertRaises(asyncio.LimitOverrunError):
             self.assert_lines(lines)
+
+
+@dataclass
+class Wrapper(Params):
+    field: TS  # no default and TS instance
+
+
+class ParamsTestCase(TestCase):
+    """ Check command line parameters rendering."""
+
+    def test_as_pairs_if_default_is_missing(self):
+        """
+        Checks that missing default does not checks value for equality with
+        dataclasses.MISSING.
+        """
+        w = Wrapper(TS(42.0))
+        self.assertEqual(w.as_pairs(), [('field', '42.0')])
Repository: jwplayer/jwplatform-py

Issue:
Client with null kwargs does not use default parameters
Currently jwplatform.Client instantiation only uses default parameters if a kwarg doesn't exist. If the kwarg is `None` this value is still used. It would be expected that `None` values for a kwarg use the default value.

**Current**
```python
>>> import jwplatform
>>> client = jwplatform.Client('key', 'secret', host=None)
>>> client._host == 'api.jwplatform.com'
False
```

**Expected**
```python
>>> import jwplatform
>>> client = jwplatform.Client('key', 'secret', host=None)
>>> client._host == 'api.jwplatform.com'
True
```


Comments:

Patch:
diff --git a/jwplatform/client.py b/jwplatform/client.py
index 18edad5..f00b7e1 100644
--- a/jwplatform/client.py
+++ b/jwplatform/client.py
@@ -61,11 +61,11 @@ class Client(object):
         self.__key = key
         self.__secret = secret
 
-        self._scheme = kwargs.pop('scheme', 'https')
-        self._host = kwargs.pop('host', 'api.jwplatform.com')
-        self._port = int(kwargs.pop('port', 80))
-        self._api_version = kwargs.pop('version', 'v1')
-        self._agent = kwargs.pop('agent', None)
+        self._scheme = kwargs.get('scheme') or 'https'
+        self._host = kwargs.get('host') or 'api.jwplatform.com'
+        self._port = int(kwargs['port']) if kwargs.get('port') else 80
+        self._api_version = kwargs.get('version') or 'v1'
+        self._agent = kwargs.get('agent')
 
         self._connection = requests.Session()
         self._connection.mount(self._scheme, RetryAdapter())


Test patch:
diff --git a/tests/test_init.py b/tests/test_init.py
index dc3ab77..3502914 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -50,3 +50,33 @@ def test_custom_initialization():
     assert 'User-Agent' in jwp_client._connection.headers
     assert jwp_client._connection.headers['User-Agent'] == \
         'python-jwplatform/{}-{}'.format(jwplatform.__version__, AGENT)
+
+
+def test_custom_initialization_empty_kwargs():
+
+    KEY = 'api_key'
+    SECRET = 'api_secret'
+    SCHEME = None
+    HOST = None
+    PORT = None
+    API_VERSION = None
+    AGENT = None
+
+    jwp_client = jwplatform.Client(
+        KEY, SECRET,
+        scheme=SCHEME,
+        host=HOST,
+        port=PORT,
+        version=API_VERSION,
+        agent=AGENT)
+
+    assert jwp_client._Client__key == KEY
+    assert jwp_client._Client__secret == SECRET
+    assert jwp_client._scheme == 'https'
+    assert jwp_client._host == 'api.jwplatform.com'
+    assert jwp_client._port == 80
+    assert jwp_client._api_version == 'v1'
+    assert jwp_client._agent is None
+    assert 'User-Agent' in jwp_client._connection.headers
+    assert jwp_client._connection.headers['User-Agent'] == \
+        'python-jwplatform/{}'.format(jwplatform.__version__)
Repository: kangasta/fdbk

Issue:
Data tools should ignore template topics
Do not add warning for missing data if topic is template topic.

Comments:

Patch:
diff --git a/fdbk/_db_connection.py b/fdbk/_db_connection.py
index af155fe..66bcf62 100644
--- a/fdbk/_db_connection.py
+++ b/fdbk/_db_connection.py
@@ -312,6 +312,9 @@ class DBConnection:
             aggregate_always,
         )
         for topic_d in topics.values():
+            if topic_d["type"] == "template":
+                continue
+
             jobs.append(
                 executor.submit(
                     self._get_topic_statistics, topic_d, *params))


Test patch:
diff --git a/tst/test_db_connection.py b/tst/test_db_connection.py
index d4c1b8a..f368696 100644
--- a/tst/test_db_connection.py
+++ b/tst/test_db_connection.py
@@ -308,3 +308,18 @@ class DBConnectionTest(TestCase):
         result = C.get_summary(topic_id, aggregate_to=3)
         data = result["statistics"][0]["payload"]["data"]["datasets"][0]["data"]
         self.assertEqual(len(data), 3)
+
+    def test_overview_ignores_templates(self):
+        data_tools = [
+            {"field":"number", "method":"line"},
+        ]
+
+        units_d = {"field":"number", "unit":"scalar"}
+
+        C = DictConnection()
+        C.add_topic("Test template", type_str="template", fields=['number'], units=[units_d], data_tools=data_tools)
+        C.add_topic("Test topic", template="Test template")
+
+        data = C.get_overview()
+        self.assertEqual(len(data["warnings"]), 1)
+        self.assertNotIn(data["warnings"][0], "template")
Repository: kaste/mockito-python

Issue:
Issue unstubbing random.randint
When trying to monkeypatch random.randint and then later unstubbing the original method does not get reinstated. Example:

```
import sys
sys.version
Out[3]: '3.10.4 (main, Mar 31 2022, 03:38:35) [Clang 12.0.0 ]'
import random
import mockito
mockito.__version__
Out[6]: '1.2.2'
random.randint(1, 10)
Out[7]: 6
mockito.when(random).randint(...).thenReturn("Mocked!")
Out[8]: <mockito.invocation.AnswerSelector at 0x7ff076012c80>
random.randint(1, 10)
Out[9]: 'Mocked!'
mockito.unstub()
random.randint(1, 10)
Traceback (most recent call last):
...
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-11-a5705e42ffa6>", line 1, in <cell line: 1>
    random.randint(1, 10)
AttributeError: module 'random' has no attribute 'randint'`
```

This seems to be because: 

not inspect.isclass(self.mocked_obj) and inspect.ismethod(original_method) 

in the method restore_method within mocking returns True when it should be False.


Comments:

Patch:
diff --git a/mockito/mocking.py b/mockito/mocking.py
index e52db5e..7ac5c8c 100644
--- a/mockito/mocking.py
+++ b/mockito/mocking.py
@@ -180,8 +180,11 @@ class Mock(object):
         # the one on its class, so we delete as well.
         if (
             not original_method
-            or not inspect.isclass(self.mocked_obj)
-            and inspect.ismethod(original_method)
+            or (
+                inspect.ismethod(original_method)
+                and not inspect.isclass(self.mocked_obj)
+                and not inspect.ismodule(self.mocked_obj)
+            )
         ):
             delattr(self.mocked_obj, method_name)
         else:


Test patch:
diff --git a/tests/modulefunctions_test.py b/tests/modulefunctions_test.py
index 6d8728f..d1429e1 100644
--- a/tests/modulefunctions_test.py
+++ b/tests/modulefunctions_test.py
@@ -98,3 +98,10 @@ class ModuleFunctionsTest(TestBase):
         from . import module
         when(module).Foo().thenReturn('mocked')
         assert module.Foo() == 'mocked'
+
+    def testUnstubFunctionOnModuleWhichIsActuallyAMethod_issue_53(self):
+        import random
+        when(random).randint(...).thenReturn("mocked")
+        assert random.randint(1, 10) == "mocked"
+        unstub(random)
+        assert random.randint(1, 10) != "mocked"