0

I am going mad over some code. Executing a program that is made to generate product suggestions randomly always yields to the error

TypeError: cannot unpack non-iterable NoneType object

Yet I cant seem to see, where a NoneType object is returned. All print statements clearly indicate that I return an object and a Boolean. Unfortunately, it's quite a bit of code and I can't seem to reproduce the error with less code.

@staticmethod
def generate_random_product(variation):
    product_options = Product.objects.all()
    if not product_options:
        raise ValidationError(
            'PRODUCT CREATION FAILED HARD COULD NOT '
            'GENERATE RANDOM PRODUCT FOR: '
            + variation.name + '... PLEASE DELETE'
            'ALL DELIVERIES THAT WERE CREATED TODAY'
        )
    random_int = random.randint(0, (product_options.count() - 1))
    return product_options[random_int], True

def generate_random_product_from_category(self, variation, count):
    if count >= 10:
        return self.generate_random_product(variation, count)
    category = variation.package.category
    product_options = category.product_set.all()
    if not product_options:
        return self.generate_random_product(variation)
    random_int = random.randint(0, (product_options.count() - 1))
    return product_options[random_int], True

def generate_random_product_from_variation(self, variation, count):
    if count >= 5:
        return self.generate_random_product_from_category(variation, count)
    product_options = variation.product_set.all()
    if not product_options:
        return self.generate_random_product_from_category(variation)
    random_int = random.randint(0, (product_options.count() - 1))
    return product_options[random_int], False

def turn_variation_into_product(self, variation, delivery, count):
    if count < 15:
        # STEP 1: generate a random product
        random_product, failed_auto = self.generate_random_product_from_variation(variation, count)
        print(random_product)
        try:
            self.turn_variation_into_product(variation, delivery, count + 1)
        except (DeliveryItem.DoesNotExist) as e:
            print('return')
            print(random_product, failed_auto)
            return random_product, failed_auto
    else:
        delivery.delete()
        raise ValidationError(
            f'all options for {variation.name} are already '
            f'included in delivery {delivery.slug} ... tried '
            f'*{count}* times')


def create_delivery_items(self, delivery):
    schema_items = delivery.delivery_schema.schemaitem_set.all()
    for schema_item in schema_items:
        if schema_item.variation and not schema_item.product:
            random_product, failed_auto = self.turn_variation_into_product(schema_item.variation, delivery, 0)
            DeliveryItem.objects.create(
                quantity=schema_item.quantity,
                variation=schema_item.variation,
                product=random_product,
                original_type=schema_item.type,
                delivery=delivery,
                failed_auto=failed_auto,
            )

The error results from this line:

random_product, failed_auto = self.turn_variation_into_product(schema_item.variation, delivery, 0)

As you can see I have print statements right above the relevant return statement. But the print statement output the correct objects.

Xen_mar
  • 8,330
  • 11
  • 51
  • 74
  • 1
    A useful debugging step might be to comment out the problematic line and replace it with `result = self.turn_variation_into_product(schema_item.variation, delivery, 0)`. Then you can inspect `result` and check to see if it has the value you'd expect. Does your editor have a Python debugger built in? A debugger is an invaluable tool for fixing logic errors. – zachdj Sep 10 '19 at 15:15
  • Also, you may want to consider posting your code at the [Code Review stack exchange](https://codereview.stackexchange.com/). As is, it's pretty tough to read/understand. For example, the `generate_random_product` takes a single argument, `variation`, which is never used. And `generate_random_product` is called with _two_ arguments on line 16. – zachdj Sep 10 '19 at 15:22
  • you are right - generate_random_product is called with two arguments in line 16, but variation is used in the message for the error. – Xen_mar Sep 10 '19 at 15:50
  • putting the values into a `result` variable returned None as expected (since the error indicated NoneType) ... I simply dont understand how I can print out values right before returning but then they end up being `None`. In my head this is impossible ... – Xen_mar Sep 10 '19 at 15:59
  • 2
    The cause of the error is shown in the duplicate question. But this really isn't an appropriate use of recursion, anyway. – Daniel Roseman Sep 10 '19 at 18:11
  • yeah - in the meanwhile I realised that ... thank you for the help. This really was the right answer. Simple for loop with range solved this very easily. – Xen_mar Sep 10 '19 at 18:12

0 Answers0