192

Basically when I have a python file like:

python-code.py

and use:

import (python-code)

the interpreter gives me syntax error.

Any ideas on how to fix it? Are dashes illegal in python file names?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689

7 Answers7

207

You should check out PEP 8, the Style Guide for Python Code:

Package and Module Names Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

Since module names are mapped to file names, and some file systems are case insensitive and truncate long names, it is important that module names be chosen to be fairly short -- this won't be a problem on Unix, but it may be a problem when the code is transported to older Mac or Windows versions, or DOS.

In other words: rename your file :)

Community
  • 1
  • 1
Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
  • 99
    the problem has nothing to do with style, it's a _syntax_ _error_ –  Apr 19 '09 at 00:09
  • 5
    As shown below, it is possible to still have a file with this name, so the style guide is very much relevant. – Paolo Bergantino Nov 19 '12 at 22:08
  • 7
    It can be very helpful to use hyphens in Python directory and file names when you explicitly want to prevent imports. For example in (say) a Django project, you may have scripts written in Python that should not be addressable as applications. You can put these in a folder like `ops-scripts` and know they can't be imported using a normal package namespace approach. Or a single script could be named `stop-website.py` for a similar effect. Any of these could still be imported via `runpy` and some other methods of course, but this helps avoid some common errors. – Chris Johnson May 29 '14 at 21:30
  • Renaming a module can be problematic, especially if you are relying on another standard. In my case, I am using python cgi files in the `cgi-bin` folder (doing unitttests on them), which is pretty standard afaik. Unless you have a rare case like this, definitely rename your module if you have control over it. – NuclearPeon Jul 09 '14 at 16:31
  • 1
    I just discovered that PyDev will allow directory names with hyphens, but will not show the classes and/or internal variables in the .py files that are contained in that directory. – user5920660 Jul 27 '17 at 01:02
142

One other thing to note in your code is that import is not a function. So import(python-code) should be import python-code which, as some have already mentioned, is interpreted as "import python minus code", not what you intended. If you really need to import a file with a dash in its name, you can do the following::

python_code = __import__('python-code')

But, as also mentioned above, this is not really recommended. You should change the filename if it's something you control.

Rick Copeland
  • 11,672
  • 5
  • 39
  • 38
  • @KevinAudleman do you have a working example of using import lib with a hyphenated file? I tried and failed. – Tom Hale Mar 30 '19 at 12:40
  • 1
    @TomHale importlib.import_module('a.b.module-1') should work. If your import_module doesn't work, I think a normal import also won't work. – Ian Lin May 08 '19 at 03:37
104

TLDR

Dashes are not illegal but you should not use them for 3 reasons:

  1. You need special syntax to import files with dashes
  2. Nobody expects a module name with a dash
  3. It's against the recommendations of the Python Style Guide

If you definitely need to import a file name with a dash the special syntax is this:

module_name = __import__('module-name')

Curious about why we need special syntax?

The reason for the special syntax is that when you write import somename you're creating a module object with identifier somename (so you can later use it with e.g. somename.funcname). Of course module-name is not a valid identifier and hence the special syntax that gives a valid one.

You don't get why module-name is not valid identifier?

Don't worry -- I didn't either. Here's a tip to help you: Look at this python line: x=var1-var2. Do you see a subtraction on the right side of the assignment or a variable name with a dash?

PS

Nothing original in my answer except including what I considered to be the most relevant bits of information from all other answers in one place

ndemou
  • 4,691
  • 2
  • 30
  • 33
  • I'm trying to use this import a pip package with a hyphen in it. `psycopg2_binary = import_module('psycopg2-binary')`. Error => `ModuleNotFoundError: No module named 'psycopg2-binary'`. But `psycopg2-binary` is installed. No idea how to include it. – Mote Zart Sep 30 '19 at 23:35
  • 1
    1 > "TLDR" 2 > "Nothing original in my answer except including what I considered to be the most relevant bits of information from all other answers in one place" Are these two above statements consistent? :) – l001d Feb 08 '21 at 20:11
  • "*Nobody expects a module name with a dash*". That's true, but everybody expects being able to reuse classes defined in another file which filename is valid (read is valid in any of the common OSes, including the most use one, Windows). So the question is more: what are the solutions for using classes defined in external files without using 'import' which is based on valid identifiers, not on valid file paths? It appears Python has not accepted solution equivalent to "import * from this-valid~filepath" which in my opinion is a problem. – mins May 18 '21 at 09:39
37

The problem is that python-code is not an identifier. The parser sees this as python minus code. Of course this won't do what you're asking. You will need to use a filename that is also a valid python identifier. Try replacing the - with an underscore.

SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 7
    +1. Never thought that the file name of Python source code should be a valid identifier, cause **the file name** will be used to refer to the module object. – andy Apr 16 '15 at 01:51
15

On Python 3 use import_module:

from importlib import import_module
python_code = import_module('python-code')

More generally,

import_module('package.subpackage.module')
e18r
  • 7,578
  • 4
  • 45
  • 40
7

You could probably import it through some __import__ hack, but if you don't already know how, you shouldn't. Python module names should be valid variable names ("identifiers") -- that means if you have a module foo_bar, you can use it from within Python (print foo_bar). You wouldn't be able to do so with a weird name (print foo-bar -> syntax error).

John Millikin
  • 197,344
  • 39
  • 212
  • 226
3

Although proper file naming is the best course, if python-code is not under our control, a hack using __import__ is better than copying, renaming, or otherwise messing around with other authors' code. However, I tried and it didn't work unless I renamed the file adding the .py extension. After looking at the doc to derive how to get a description for .py, I ended up with this:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

It created a new file python-codec on the first run.

Ale
  • 887
  • 10
  • 14
  • 2
    "*Although proper file naming is the best course*", proper file naming is a matter of OS, not a matter of Pythonic thinking. Using dashes in filenames is valid for OSes. Python defines what is a valid identifier within Python programs, that's not the same. – mins May 18 '21 at 09:45