We've long had a problem with using namespace aliases inconsistently, and a recent discussion on the review for
DM-2305 emphasized the need to actually resolve this rather than just writing different files differently.
So, as the loudest member of the "no aliases" camp, here's a proposal that still involves some aliases that I could get behind. The tl;dr version is:
- No file-scope aliases in C++.
- File-scope aliases in Python like "afw_geom" rather than "afwGeom".
- Tiny aliases permitted in limited scopes.
- Use in new files immediately; old files will be migrated when we do the package reorg of
DM-2003(later in S15).
Here's the detailed proposal:
Namespace aliases shall not be used at file or namespace scope in C++. Instead, as many namespace components as needed to disambiguate a name should be used, within the appropriate namespace scope for the current package. More namespace components can be used than are strictly necessary to satisfy the compiler; the goal should be to provide clarity to human readers. The lsst:: namespace component should not be included except in the rare case where the next namespace component is potentially ambiguous (i.e. both ::lsst::foo and ::foo are present), or in a header where it is needed to unconfuse Swig.
For example, here is how we could refer to various classes from within meas_algorithms:
In addition, in contexts where a namespace component conflicts with a frequently-used variable name, additional prefix components should be used (i.e. prefer "afw::image" to "image", because the latter is a very common variable name).
In function or class scopes, any namespace alias may be used (even much more abbreviated aliases), but these should be limited to cases where the alias is used many times within the function, and usually a typedef or full using declaration is preferred in these contexts.
Python module aliases used at module scope must be formed from the last N components of their fully-qualified name, joined by underscores instead of periods, with no change in capitalization. For example, lsst.afw.geom.ellipses could be aliased to afw_geom_ellipses, geom_ellipses, or just ellipses, and which of these is chosen is left to the judgement of individual developers. However, the same guidelines discussed for use of C++ namespace components should be applied when determining which namespace components to use in Python aliases: use as many components as needed to avoid reader ambiguity. When only the last component is used, the
import <package>.<module> as <module>
form should be used, rather than
from <package> import <module>,
to improve readability next to other nearby import statements.
from <package>.<module> import <names>
form is also permitted, but the
from <package>.<module> import *
form is not, except in cases where names are explicitly being lifted to package or subpackage scope in an __init__.py.
While this proposal still leaves some room for developer preference, it's much less room than the current situation, and in particular I believe it's enough to be able to reliably search for all possible forms of a namespace with a complex regex, and (perhaps more importantly) search for nearly all possible forms of a namespace with a very simple search.
Ideally, we'd be able to say
from lsst import afw.geom
import lsst.afw.geom as afw_geom,
but alas, we cannot - so I think the latter is the best we can hope for, and much better than the current
import lsst.afw.geom as afwGeom
That's because eliminates having the same name capitalized differently in different contexts, and it minimizes having the same name punctuated differently in different contexts, both of which complicate searching - and, to the LSST-uninitiated, code reading - unnecessarily. It also eliminates capital letters from our module aliases, bringing them in line with the PEP 8 guidelines for module and package names (I think a name that's used to refer to a module should look like a module name as much as possible, and our current ones don't).
If this proposal is adopted, I propose we start using it in new files immediately, but leave old files in their current form unless more than ~80% of the file is being rewritten. Old files will be migrated to the new form as part of
DM-2003 later in S15, where the namespace themselves will be changing for most packages, and hence we'll need to touch all of the same code anyway. Delaying the migration also leaves us time to synchronize with the HSC fork without complicating those cherry-picks with nomenclature-only changes.