@@ -210,9 +210,10 @@ def __init__(
210210 # Process the timecode value, storing it as an exact number of frames.
211211 if isinstance (timecode , str ):
212212 self ._seconds = self ._timecode_to_seconds (timecode )
213- self ._frame_num = self ._seconds_to_frames (self ._timecode_to_seconds ( timecode ) )
213+ self ._frame_num = self ._seconds_to_frames (self ._seconds )
214214 else :
215215 self ._frame_num = self ._parse_timecode_number (timecode )
216+ self ._seconds = timecode if isinstance (timecode , float ) else None
216217
217218 @property
218219 def frame_num (self ) -> ty .Optional [int ]:
@@ -379,14 +380,14 @@ def _timecode_to_seconds(self, input: str) -> float:
379380 Raises:
380381 ValueError: Value could not be parsed correctly.
381382 """
382- assert self ._framerate is not None
383+ assert self ._framerate is not None and self . _framerate > MAX_FPS_DELTA
383384 input = input .strip ()
384385 # Exact number of frames N
385386 if input .isdigit ():
386387 timecode = int (input )
387388 if timecode < 0 :
388389 raise ValueError ("Timecode frame number must be positive." )
389- return timecode * self .framerate
390+ return timecode / self .framerate
390391 # Timecode in string format 'HH:MM:SS[.nnn]' or 'MM:SS[.nnn]'
391392 elif input .find (":" ) >= 0 :
392393 values = input .split (":" )
@@ -438,33 +439,45 @@ def _get_other_as_frames(self, other: ty.Union[int, float, str, "FrameTimecode"]
438439 def __eq__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
439440 if other is None :
440441 return False
442+ if _compare_as_fixed (self , other ):
443+ return self ._frame_num == other ._frame_num
441444 if self ._timecode or self ._seconds is not None :
442445 return self .seconds == self ._get_other_as_seconds (other )
443446 return self .frame_num == self ._get_other_as_frames (other )
444447
445448 def __ne__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
446449 if other is None :
447450 return True
451+ if _compare_as_fixed (self , other ):
452+ return self ._frame_num != other ._frame_num
448453 if self ._timecode or self ._seconds is not None :
449454 return self .seconds != self ._get_other_as_seconds (other )
450455 return self .frame_num != self ._get_other_as_frames (other )
451456
452457 def __lt__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
458+ if _compare_as_fixed (self , other ):
459+ return self ._frame_num < other ._frame_num
453460 if self ._timecode or self ._seconds is not None :
454461 return self .seconds < self ._get_other_as_seconds (other )
455462 return self .frame_num < self ._get_other_as_frames (other )
456463
457464 def __le__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
465+ if _compare_as_fixed (self , other ):
466+ return self ._frame_num <= other ._frame_num
458467 if self ._timecode or self ._seconds is not None :
459468 return self .seconds <= self ._get_other_as_seconds (other )
460469 return self .frame_num <= self ._get_other_as_frames (other )
461470
462471 def __gt__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
472+ if _compare_as_fixed (self , other ):
473+ return self ._frame_num > other ._frame_num
463474 if self ._timecode or self ._seconds is not None :
464475 return self .seconds > self ._get_other_as_seconds (other )
465476 return self .frame_num > self ._get_other_as_frames (other )
466477
467478 def __ge__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> bool :
479+ if _compare_as_fixed (self , other ):
480+ return self ._frame_num >= other ._frame_num
468481 if self ._timecode or self ._seconds is not None :
469482 return self .seconds >= self ._get_other_as_seconds (other )
470483 return self .frame_num >= self ._get_other_as_frames (other )
@@ -495,11 +508,14 @@ def __iadd__(self, other: ty.Union[int, float, str, "FrameTimecode"]) -> "FrameT
495508 self ._frame_num = None
496509 return self
497510
498- if self ._seconds and other ._seconds :
511+ other_has_seconds = isinstance (other , FrameTimecode ) and other ._seconds
512+ if self ._seconds is not None and other_has_seconds :
499513 self ._seconds = max (0 , self ._seconds + other ._seconds )
500514 return self
501515
502516 self ._frame_num = max (0 , self ._frame_num + self ._get_other_as_frames (other ))
517+ if self ._seconds is not None :
518+ self ._seconds = max (0.0 , self ._seconds + self ._get_other_as_seconds (other ))
503519 return self
504520
505521 def __add__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> "FrameTimecode" :
@@ -533,11 +549,14 @@ def __isub__(self, other: ty.Union[int, float, str, "FrameTimecode"]) -> "FrameT
533549 self ._frame_num = None
534550 return self
535551
536- if self ._seconds and other ._seconds :
552+ other_has_seconds = isinstance (other , FrameTimecode ) and other ._seconds
553+ if self ._seconds is not None and other_has_seconds :
537554 self ._seconds = max (0 , self ._seconds - other ._seconds )
538555 return self
539556
540557 self ._frame_num = max (0 , self ._frame_num - self ._get_other_as_frames (other ))
558+ if self ._seconds is not None :
559+ self ._seconds = max (0.0 , self ._seconds - self ._get_other_as_seconds (other ))
541560 return self
542561
543562 def __sub__ (self , other : ty .Union [int , float , str , "FrameTimecode" ]) -> "FrameTimecode" :
@@ -585,3 +604,7 @@ def _get_other_as_seconds(self, other: ty.Union[int, float, str, "FrameTimecode"
585604 if isinstance (other , FrameTimecode ):
586605 return other .seconds
587606 raise TypeError ("Unsupported type for performing arithmetic with FrameTimecode." )
607+
608+
609+ def _compare_as_fixed (a : FrameTimecode , b : ty .Any ) -> bool :
610+ return a ._framerate is not None and isinstance (b , FrameTimecode ) and b ._framerate is not None
0 commit comments