This question already has answers here:
How to import module when module name has a '-' dash or hyphen in it?
(8 answers)
Closed 5 years ago.
How to import the directory contains - ?
from gib-bin.Test import print_test
print_test()
Error:
from gib-bin.Test import print_test
^
SyntaxError: invalid syntax
You don't. Either remove the Hyphen or Replace it with an Underscore.
Name the package gib_bin or gibbin.
Also look at PEP 8:
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.
Related
I used PyScaffold to create a template for a PyPi package I am creating, bbox-utils. The generated __init__.py is as follows:
from pkg_resources import DistributionNotFound, get_distribution
try:
# Change here if project is renamed and does not equal the package name
dist_name = "bbox-utils"
__version__ = get_distribution(dist_name).version
except DistributionNotFound: # pragma: no cover
__version__ = "unknown"
finally:
del get_distribution, DistributionNotFound
I'm a bit confused what name to use for dist_name. I tried doing:
>>> from pkg_resources import DistributionNotFound, get_distribution
>>> get_distribution('bbox_utils').version
'0.0.1'
>>> get_distribution('bbox-utils').version
'0.0.1'
and I get the same version whether I replace the hyphen with an underscore or leave it as is. Which should I do?
Edit:
Here is the GitHub repo
Here is PyPi link
You generally should not name your packages or modules using dashes although you can. Since the import statement does not use quotes, using a dash is interpreted as using a minus sign, which will result in an illegal syntax during import if using the dash name.
There are ways around this, such as importing with underscores but installing via pip/searching pypi with dashes, but it is a needless inconsistency that can cause frustration. Generally the python approach is to be able to import modules as valid module objects whose variable name equals the actual module name. When naming projects, it is therefore better to use underscores instead of dashes.
That being said, pkg_resources seems to actually replace all non-alphanumeric and non-dot characters with dashes when resolving project names.
assert(get_distribution('bbox_utils').project_name == 'bbox-utils')
assert(get_distribution('bbox-utils').project_name == 'bbox-utils')
So you should be able to use either expression interchangeably in the code snippet in the question.
This question already has answers here:
Check whether a path is valid in Python without creating a file at the path's target
(6 answers)
Closed 4 years ago.
I recently zipped up a number of files created by a script I wrote and sent them to a Windows-using colleague. He could not unzip the archive, since some of my filenames contained a : which isn’t legal on Windows.
It’s trivial to strip out the :, but what if there are other characters that I’m unaware of as being illegal in Windows path/filenames?
I wondered whether pathlib’s “pure” path objects would flag illegal characters in any way, but they do not as far as I can determine:
>>> from pathlib import PurePosixPath, PureWindowsPath
>>> pp = PurePosixPath("foo/bar:baz.txt")
>>> wp = PureWindowsPath(pp)
>>> print(wp)
foo\bar:baz.txt
Given that I do not have easy access to a Windows machine for testing, is there a simple way to ensure path/filenames generated by Python are “Windows-safe”?
The most simple solution would just be to avoid using reserved windows characters when building out your filename.
Looking at the following link: Naming Files, Path and Namespaces it quotes the following as being Windows illegal characters:
Use any character in the current code page for a name, including Unicode characters and characters in the extended character set (128–255), except for the following:
The following reserved characters:
< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
I'd like to escape ":" and/or "=" as the name in a configuration file.
Does anyone know how to achieve this?
I try backslash "\", it does not work.
If you're using Python 3, you don't need to. Look at the Python docs section on Customizing Parser Behavior. By default, configparser uses ":" and "=" as delimiters, but you can specify different delimiters when you create the configparser object:
import configparser
parser = configparser.ConfigParser(delimiters=('?', '*'))
In this example, the default delimiters have been replaced with a question mark and an asterisk. You can change the delimiters to whatever characters you want that won't conflict with the information you need to put in the config file.
The above listed method will only work for Python 3, as the Python 2 ConfigParser is hard-coded to recognize equal signs and colons as delimiters. According to this SO question, there is a backported configparser available for the 2.7 intepreter at https://pypi.python.org/pypi/configparser. See if that will work for you.
This question already has answers here:
Type of compiled regex object in python
(10 answers)
Closed 5 years ago.
I am writing a function to deal with pre-compiled regular expressions. How do I define this explicitly? E.g.
def use_regular_expression(regular_expression: ???):
pass
What I am to write in place of "???" to only accept what re.compile outputs given a valid regular expression string?
print(type(re.compile(''))) says _sre.SRE_Pattern and the PyCharm IDE suggests it's re.__Regex but neither seems to work no matter what of the obvious ways I try to import and specify them.
Thanks to whoever has marked my question to be a duplicate of this one (I've failed to find it myself unfortunately) I have found the correct (i.e. exactly what I was looking for) answer written by #flying-sheep, let me cite it here for those who may happen to stumble upon this instance of the question:
It's typing.re.Pattern.
E.g.
from typing.re import Pattern
my_re = re.compile('foo')
assert isinstance(my_re, Pattern)
I have check source code of re. In its source code, there is one line to check the type of input.
if isinstance(pattern, _pattern_type): #line 294
And then I check what _pattern_type is.
_pattern_type = type(sre_compile.compile("", 0)) #It also gives "_sre.SRE_Pattern"
So as you can see, even in re's source code, there is no way to explicitly point out the class of a compiled regex.
Unfortunately, your question seems unsolvable.
Further, using annotations in variable definition just tell IDE to check, but not really restrict in runtime. I recommend you to use:
assert type(regular_expression) == type(re.compile("", 0))
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?
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 :)
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.
TLDR
Dashes are not illegal but you should not use them for 3 reasons:
You need special syntax to import files with dashes
Nobody expects a module name with a dash
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
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.
On Python 3 use import_module:
from importlib import import_module
python_code = import_module('python-code')
More generally,
import_module('package.subpackage.module')
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).
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.