Skip to content

variable 'referenced before assignment' warning, error in all() with .pxd but not .pyx #3477

@rob-miller

Description

@rob-miller

The following is a standalone example of a problem I've run into trying to accelerate some code:

given allExt.py (takes a set of words and checks if 3rd letter in each is a vowel):

class a3v(object):
    def __init__(self, inset):
        self.myStrSet = inset   # set input word list as an attribute on  class instance

    def all3Vowels(self):     # test if 3rd letter of each word is a vowel
        vndx = 2                    # local variable for 3rd letter index
        inStrSet = self.myStrSet    # local variable for class instance word list
        if all(
            ltr in ("a", "e", "i", "o", "u")
            for ltr in (w[vndx] for w in inStrSet)
        ):
            return True
        return False

and tst.py:

#!/usr/local/bin/python3
import allExt

a3vL = allExt.a3v(["the", "bright", "flower"])

if a3vL.all3Vowels():
   print('yes')
else:
   print('no')

The code runs without issue, and fits with examples I have found in the cython docs. However, when augmented with allExt.pxd:

import cython

cdef class a3v:
     cdef public list myStrSet

     @cython.locals(vndx=int, inStrSet=list, ltr=str)
     cpdef bint all3Vowels(self)

Upon compiling as shown I get:

rob@nova-370:01 14:45:55 atmNdx $ cythonize -3 -f -i allExt.py allExt.pxd
[1/1] Cythonizing /Users/rob/sync/rgithub/cython/atmNdx/allExt.py
warning: allExt.py:12:26: local variable 'vndx' referenced before assignment

Error compiling Cython file:
------------------------------------------------------------
...
    def all3Vowels(self):
        vndx = 2
        inStrSet = self.myStrSet
        if all(
            ltr in ("a", "e", "i", "o", "u")
            for ltr in (w[vndx] for w in inStrSet)
                                        ^
------------------------------------------------------------

allExt.py:12:41: local variable 'inStrSet' referenced before assignment
Traceback (most recent call last):

OTOH, the equivalent (?) pyx version allExt.pyx:

class a3v(object):
    def __init__(self, inset):
        self.myStrSet = inset

    def all3Vowels(self):
        cdef int vndx = 2
        cdef list inStrSet = self.myStrSet
        cdef str ltr
        if all(
            ltr in ("a", "e", "i", "o", "u")
            for ltr in (w[vndx] for w in inStrSet)
        ):
            return True
        return False

compiles and runs without issue.

Have I missed something in the docs or some other simple issue?
Thank you.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions