Opened 8 years ago

Closed 8 years ago

#23612 closed Bug (fixed)

Relative fixture paths not working on Windows 8.1

Reported by: Brandon Taylor Owned by: nobody
Component: Testing framework Version: dev
Severity: Normal Keywords: windows fixtures
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Simon Charette)

I have a Django 1.6.6 project that is not loading fixtures from relative paths using Python 2.7.8 on Windows 8.1. Works just fine in Linux.

Example Test Case:

# cart/tests.py

class CartTestBase(TestCase):
    fixtures = ['products/fixtures/product_categories.json',
    'products/fixtures/brands.json', 'products/fixtures/products.json']

Which fits into a directory structure of:

ecomm_app/
    cart/
        __init__.py
        models.py
        tests.py
        . . .
      
    products/
        fixtures/
            products/fixtures/product_categories.json
            products/fixtures/brands.json
            products/fixtures/products.json
        __init__.py
        models.py
        . . .

The specific error message is:

UserWarning: No fixture named 'products/fixtures/products' found.
warnings.warn("No fixture named '%s' found." % fixture_name)

The corresponding app modules are listed in INSTALLED_APPS and work fine otherwise. Specifying an absolute path does work, but obviously isn't cross-platform. Specifying a root-relative path does not work, e.g.: /products/fixtures/brands.json

Moving the fixtures to /cart/fixtures/ and referencing them by name only works.

Change History (13)

comment:1 Changed 8 years ago by Simon Charette

Description: modified (diff)

First I assume the files in products/fixtures/ are named <name>.json and not products/fixtures/<name>.json.

I don't have Windows VM at hand but isn't it using backslashes (\) as directory separators?

comment:2 Changed 8 years ago by Brandon Taylor

That is correct. I took a look at the directories returned by fixture_dirs() in core/management/loaddata.py and the paths are correct, but it doesn't seem to be concatenating the paths correctly if I specify a directory structure plus the file name.

The paths returned by fixture_dirs() are in: C:\\path\\path\\path format.

Leaving the directory structure off entirely works as it picks up the products/fixtures/ directory, but you'd most likely run into issues if there were fixtures with duplicate names.

comment:3 Changed 8 years ago by Brandon Taylor

I think the problem is with line 189 in loaddata.py. It's checking for os.path.sep which on Windows is \. Aren't we always supposed to use forward slashes / with Python on Windows? Changing os.path.sep to / allows the relative paths to work.

Last edited 8 years ago by Brandon Taylor (previous) (diff)

comment:4 Changed 8 years ago by Brandon Taylor

How about changing line 189 to:

if os.path.sep in os.path.normpath(fixture_name):

That way it is still based on the path separator for the os. Paths to fixtures can still be written using / so they are consistent with other paths in Django like template and static file directories, where the documentation specifically states to use forward slashes.

Last edited 8 years ago by Brandon Taylor (previous) (diff)

comment:5 Changed 8 years ago by Simon Charette

Triage Stage: UnreviewedAccepted
Version: 1.7master

comment:6 Changed 8 years ago by Brandon Taylor

I submitted a Pull Request with a fix: https://github.com/django/django/pull/3324

Running the test suite yields no failures.

comment:7 Changed 8 years ago by Collin Anderson

Has patch: set

comment:8 Changed 8 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: newclosed

In 16ed35fafc0583b485a0289afda632f8261ecc96:

Fixed #23612 -- Normalized fixuture paths to allow referencing relative paths on Windows.

comment:9 Changed 8 years ago by Jaap Roes

The test introduced with this fix doesn't pass. Created a separate ticket #23633

comment:10 Changed 8 years ago by Tim Graham

Resolution: fixed
Status: closednew

I think we should try to make this test work when running tests via ./tests/runtests.py since all the other tests work and we have made similar efforts to fix tests that didn't (e.g. d11e83620380fdd98679b09062eefd25f0a98e21).

comment:11 Changed 8 years ago by Tim Graham

Here's a PR to allow the above.

comment:12 Changed 8 years ago by Tim Graham <timograham@…>

In 28da093ae24c3fb9070055df5d727a9c51c9cf83:

Allowed test from refs #23612 to be run from a directory other than tests.

comment:13 Changed 8 years ago by Tim Graham

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top