donnemartin/interactive-coding-challenges · error · TypeError

max_num cannot be None

Error message

max_num cannot be None

What it means

Raised by PrimeGenerator.generate_primes (Sieve of Eratosthenes) when max_num is None. The sieve immediately allocates [True] * max_num, which would raise a confusing TypeError on None; the guard makes the contract explicit: an integer upper bound is required.

Source

Thrown at math_probability/generate_primes/check_prime_solution.ipynb:101

   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "\n",
    "class PrimeGenerator(object):\n",
    "\n",
    "    def generate_primes(self, max_num):\n",
    "        if max_num is None:\n",
    "            raise TypeError('max_num cannot be None')\n",
    "        array = [True] * max_num\n",
    "        array[0] = False\n",
    "        array[1] = False\n",
    "        prime = 2\n",
    "        while prime <= math.sqrt(max_num):\n",
    "            self._cross_off(array, prime)\n",
    "            prime = self._next_prime(array, prime)\n",
    "        return array\n",
    "\n",
    "    def _cross_off(self, array, prime):\n",
    "        for index in range(prime*prime, len(array), prime):\n",
    "            # Start with prime*prime because if we have a k*prime\n",
    "            # where k < prime, this value would have already been\n",
    "            # previously crossed off\n",
    "            array[index] = False\n",
    "\n",
    "    def _next_prime(self, array, prime):\n",
    "        next = prime + 1\n",

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Pass an integer upper bound, e.g. generate_primes(100)
  2. Default the parameter at the call site: generate_primes(limit or 100)
  3. Validate config/env-derived limits before calling

Example fix

# before
gen.generate_primes(int(config.get('limit')))  # get returns None -> int(None) crashes earlier; direct pass-through raises here

# after
limit = config.get('limit')
if limit is None:
    limit = 100
gen.generate_primes(int(limit))
Defensive patterns

Strategy: validation

Validate before calling

max_num = max_num if max_num is not None else DEFAULT_LIMIT
gen.generate_primes(max_num)

Type guard

def is_positive_int(x): return isinstance(x, int) and x >= 0

Try / catch

try:
    gen.generate_primes(limit)
except TypeError:
    gen.generate_primes(DEFAULT_LIMIT)

Prevention

When it happens

Trigger: Calling PrimeGenerator().generate_primes(None), e.g. passing a limit read from argv/config that was never set, or int(os.environ.get('LIMIT')) where the env var is missing.

Common situations: CLI scripts and notebooks where the limit is optional and defaults to None; parameterized tests.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/6c194b722267ce00. Report an issue: GitHub.