pytest-dev / pytest-dev/pytest-flask

PicklingError using live_server fixture on Windows

Open
#54 13 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug stale
Dominant language
Python
Stars
499
Forks
93
PR merge metrics
No merged PRs in 30d

Description

Not sure if Windows is supposed to be supported, but for me it fails on Windows 10 Python 2.7.12 with the following error when live_server fixture used:

request = <SubRequest '_push_request_context' for <Function 'test_get_url'>>                                                                                       
                                                                                                                                                                   
    @pytest.fixture(autouse=True)                                                                                                                                  
    def _push_request_context(request):                                                                                                                            
        """During tests execution request context has been pushed, e.g. `url_for`,                                                                                 
        `session`, etc. can be used in tests as is::                                                                                                               
                                                                                                                                                                   
            def test_app(app, client):                                                                                                                             
                assert client.get(url_for('myview')).status_code == 200                                                                                            
                                                                                                                                                                   
        """                                                                                                                                                        
        if 'app' not in request.fixturenames:                                                                                                                      
            return                                                                                                                                                 
                                                                                                                                                                   
        app = request.getfuncargvalue('app')                                                                                                                       
                                                                                                                                                                   
        # Get application bound to the live server if ``live_server`` fixture                                                                                      
        # is applyed. Live server application has an explicit ``SERVER_NAME``,                                                                                     
        # so ``url_for`` function generates a complete URL for endpoint which                                                                                      
        # includes application port as well.                                                                                                                       
        if 'live_server' in request.fixturenames:                                                                                                                  
>           app = request.getfuncargvalue('live_server').app                                                                                                       
                                                                                                                                                                   
..\..\..\..\python-virtualenv\shadow\Lib\site-packages\pytest_flask\plugin.py:85:                                                                                  
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _                                                                                    
..\..\..\..\python-virtualenv\shadow\Lib\site-packages\pytest_flask\fixtures.py:127: in live_server                                                                
    server.start()                                                                                                                                                 
..\..\..\..\python-virtualenv\shadow\Lib\site-packages\pytest_flask\fixtures.py:64: in start                                                                       
    self._process.start()                                                                                                                                          
c:\python27\Lib\multiprocessing\process.py:130: in start                                                                                                           
    self._popen = Popen(self)                                                                                                                                      
c:\python27\Lib\multiprocessing\forking.py:277: in __init__                                                                                                        
    dump(process_obj, to_child, HIGHEST_PROTOCOL)                                                                                                                  
c:\python27\Lib\multiprocessing\forking.py:199: in dump                                                                                                            
    ForkingPickler(file, protocol).dump(obj)                                                                                                                       
c:\python27\Lib\pickle.py:224: in dump                                                                                                                             
    self.save(obj)                                                                                                                                                 
c:\python27\Lib\pickle.py:331: in save                                                                                                                             
    self.save_reduce(obj=obj, *rv)                                                                                                                                 
c:\python27\Lib\pickle.py:425: in save_reduce                                                                                                                      
    save(state)                                                                                                                                                    
c:\python27\Lib\pickle.py:286: in save                                                                                                                             
    f(self, obj) # Call unbound method with explicit self                                                                                                          
c:\python27\Lib\pickle.py:655: in save_dict                                                                                                                        
    self._batch_setitems(obj.iteritems())                                                                                                                          
c:\python27\Lib\pickle.py:687: in _batch_setitems                                                                                                                  
    save(v)                                                                                                                                                        
c:\python27\Lib\pickle.py:286: in save                                                                                                                             
    f(self, obj) # Call unbound method with explicit self                                                                                                          
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _                                                                                    
                                                                                                                                                                   
self = <multiprocessing.forking.ForkingPickler instance at 0x0000000007EDBA08>                                                                                     
obj = <function <lambda> at 0x00000000081B9DD8>, name = '<lambda>'                                                                                                 
pack = <built-in function pack>                                                                                                                                    
                                                                                                                                                                   
    def save_global(self, obj, name=None, pack=struct.pack):                                                                                                       
        write = self.write                                                                                                                                         
        memo = self.memo                                                                                                                                           
                                                                                                                                                                   
        if name is None:                                                                                                                                           
            name = obj.__name__                                                                                                                                    
                                                                                                                                                                   
        module = getattr(obj, "__module__", None)                                                                                                                  
        if module is None:                                                                                                                                         
            module = whichmodule(obj, name)                                                                                                                        
                                                                                                                                                                   
        try:                                                                                                                                                       
            __import__(module)                                                                                                                                     
            mod = sys.modules[module]                                                                                                                              
            klass = getattr(mod, name)                                                                                                                             
        except (ImportError, KeyError, AttributeError):                                                                                                            
            raise PicklingError(                                                                                                                                   
                "Can't pickle %r: it's not found as %s.%s" %                                                                                                       
>               (obj, module, name))                                                                                                                               
E           PicklingError: Can't pickle <function <lambda> at 0x00000000081B9DD8>: it's not found as pytest_flask.fixtures.<lambda>                                

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the live_server fixture failure on Windows with Python 2.7.12, then inspect pytest_flask/plugin.py around line 85 and pytest_flask/fixtures.py around lines 64 and 127. Trace the multiprocessing startup that raises PicklingError and establish whether the expected result is a working live_server fixture or a documented Windows support limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.