Ticket #618 (new defect)

Opened 14 months ago

Last modified 13 months ago

Bytecode-only (pyc) controllers not recognized

Reported by: Ivan Owned by: bbangert
Priority: high Milestone:
Component: dispatch/routing Version: 0.9.6
Severity: major Keywords:
Cc:

Description

I've compiled to bytecode all files (python -m compileall .) in pylons project, then removed all source files. When started, router is unable to locate simple controller (404, not found).

However I can do nasty trick - the problematic file is lets say - controllers/auth.pyc. You can do :
1) paster serve --reload development.ini
2) In browser : locahost:8000/auth/index/
and it wont work (404), but
1) stop paster
2) rename controllers/auth.pyc to controllers/auth.py
3) In browser : localhost:8000/auth/index/
4) will show 'internal server error'
5) rename file back to /controllers/auth.pyc
6) refresh page - it will work

IMO very strange behavior. Dont exactly know if it is a router issue, or sobe other component. Any ideas how to fix it ?

Change History

Changed 13 months ago by jssk

I had the same problem and here's my quick fix: You can add your own controller scanner to the mapper as an argument:

I copied the function from controller_scan from routes/utils and added support for pyc files.

...
def controller_scan_py_and_pyc(directory=None):
    """Scan a directory for py & pyc files and use them as controllers"""
    if directory is None:
        return []

    def find_controllers(dirname, prefix=''):
        """Locate controllers in a directory"""
        controllers = []
        for fname in os.listdir(dirname):
            filename = os.path.join(dirname, fname)

            if os.path.isfile(filename):
                if re.match('^[^_]{1,1}.*\.py$', fname):
                    controllers.append(prefix + fname[:-3])
                elif re.match('^[^_]{1,1}.*\.pyc$', fname):
                    controllers.append(prefix + fname[:-4])
            elif os.path.isdir(filename):
                controllers.extend(find_controllers(filename,
                                                    prefix=prefix+fname+'/'))

        return controllers

    def longest_first(fst, lst):
        """Compare the length of one string to another, shortest goes first"""
        return cmp(len(lst), len(fst))
    controllers = find_controllers(directory)
    controllers.sort(longest_first)
    return controllers

def make_map():
    """Create, configure and return the routes Mapper"""
    map = Mapper(controller_scan=controller_scan_py_and_pyc,
                 directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])
etc...
Note: See TracTickets for help on using tickets.


Powered by Pylons - Contact Administrators