Skip to content

Commit

Permalink
Implement support for __add__ and __sub__ and basic timedelta math
Browse files Browse the repository at this point in the history
  • Loading branch information
mreitinger committed Mar 10, 2024
1 parent 3b4ae2b commit 9f5a8b4
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
4 changes: 4 additions & 0 deletions p5lib/Python2/Internals.pm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ my $arithmetic_operations = {
'+' => sub {
my ($left, $right) = @_;

return $left->__add__($right) if $left->can('__add__');

if ($left->isa('Python2::Type::Scalar::Num') and ($right->isa('Python2::Type::Scalar::Num'))) {
return \Python2::Type::Scalar::Num->new($left->__tonative__ + $right->__tonative__);
}
Expand All @@ -149,6 +151,8 @@ my $arithmetic_operations = {
'-' => sub {
my ($left, $right) = @_;

return $left->__sub__($right) if $left->can('__add__');

$left = $left->__tonative__;
$right = $right->__tonative__;

Expand Down
37 changes: 37 additions & 0 deletions p5lib/Python2/Type/Object/StdLib/datetime/timedelta.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ use Scalar::Util::Numeric qw(isfloat);

sub new { bless({}, shift); }

sub new_from_duration {
my ($self, $duration) = @_;

die Python2::Type::Exception->new('TypeError', 'new_from_duration() expects a DateTime::Duration object, got ' . ref($duration))
unless ref($duration) eq 'DateTime::Duration';

return \bless({
duration => $duration
}, ref($self));
}

sub __call__ {
my $self = shift;
my $named_arguments = pop;
Expand Down Expand Up @@ -103,4 +114,30 @@ sub __print__ {
return sprintf("%s:%s:%s", $h, $m, $s);
}

sub __tonative__ { shift->{duration} }

sub __add__ {
my ($self, $other) = @_;

die Python2::Type::Exception->new('TypeError', 'Unsupported type for addition to timedelta: ' . $other->__type__ . ', expected timedelta.')
unless ref($other) eq ref($self);

return $self->new_from_duration(
$self->__tonative__ + $other->__tonative__
);
}

sub __sub__ {
my ($self, $other) = @_;

die Python2::Type::Exception->new('TypeError', 'Unsupported type for subtraction to timedelta: ' . $other->__type__ . ', expected timedelta.')
unless ref($other) eq ref($self);

return $self->new_from_duration(
$self->__tonative__ - $other->__tonative__
);
}



1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from datetime import timedelta

print(timedelta(1) + timedelta(2))
print(timedelta(2) - timedelta(1))

try:
timedelta(1) + 'a'
except TypeError:
print "timedelta addition with invalid type raises TypeError, as expected."

try:
timedelta(1) - 'a'
except TypeError:
print "timedelta subtraction with invalid type raises TypeError, as expected."

0 comments on commit 9f5a8b4

Please sign in to comment.