Repository: hgrecco/pint

Issue:
Define unit without symbol
Is it currently possible to define a unit without symbol (but with aliases) in a text file? Currently we have behavior such as:

```
>>> print('{:}'.format(ureg['1 millenium']))
1 millenium
>>> print('{:~}'.format(ureg['1 millenium']))
1 millenia
```

Surely no one intended "millenia" to be the symbol for millennium (the multiple misspelling is another matter). The unit is defined as:

```
millenium = 1000 * year = millenia = milenia = milenium
```

It is possible to set an empty symbol with

```
millenium = 1000 * year = = millenia = milenia = milenium
```

but that still gives a unit with a symbol (that happens to be an empty string). Is there another way? Or should this be the preferred way, and then the code should change an empty symbol to `None`?

Comments:

Patch:
diff --git a/pint/constants_en.txt b/pint/constants_en.txt
index 19616a0..dba75ae 100644
--- a/pint/constants_en.txt
+++ b/pint/constants_en.txt
@@ -10,7 +10,7 @@ speed_of_light = 299792458 * meter / second = c
 standard_gravity = 9.806650 * meter / second ** 2 = g_0 = g_n = gravity
 vacuum_permeability = 4 * pi * 1e-7 * newton / ampere ** 2 = mu_0 = magnetic_constant
 vacuum_permittivity = 1 / (mu_0 * c **2 ) = epsilon_0 = electric_constant
-Z_0 = mu_0 * c = impedance_of_free_space = characteristic_impedance_of_vacuum
+impedance_of_free_space = mu_0 * c = Z_0 = characteristic_impedance_of_vacuum
 
 # 0.000 000 29 e-34
 planck_constant = 6.62606957e-34 J s = h
@@ -29,7 +29,7 @@ molar_gas_constant = 8.3144621 J mol^-1 K^-1 = R
 fine_structure_constant = 7.2973525698e-3
 
 # 0.000 000 27 e23
-avogadro_number = 6.02214129e23 mol^-1 =N_A
+avogadro_number = 6.02214129e23 mol^-1 = N_A
 
 # 0.000 0013 e-23
 boltzmann_constant = 1.3806488e-23 J K^-1 = k
diff --git a/pint/default_en.txt b/pint/default_en.txt
index e796636..b329087 100644
--- a/pint/default_en.txt
+++ b/pint/default_en.txt
@@ -58,17 +58,17 @@ count = []
 [acceleration] = [length] / [time] ** 2
 
 # Angle
-turn = 2 * pi * radian = revolution = cycle = circle
+turn = 2 * pi * radian = _ = revolution = cycle = circle
 degree = pi / 180 * radian = deg = arcdeg = arcdegree = angular_degree
 arcminute = arcdeg / 60 = arcmin = arc_minute = angular_minute
-arcsecond = arcmin / 60 =  arcsec = arc_second = angular_second
+arcsecond = arcmin / 60 = arcsec = arc_second = angular_second
 steradian = radian ** 2 = sr
 
 # Area
 [area] = [length] ** 2
 are = 100 * m**2
 barn = 1e-28 * m ** 2 = b
-cmil = 5.067075e-10 * m ** 2 = circular_mils
+circular_mil = 5.067075e-10 * m ** 2 = cmil = circular_mils
 darcy = 9.869233e-13 * m ** 2
 hectare = 100 * are = ha
 
@@ -81,8 +81,8 @@ molar = mol / (1e-3 * m ** 3) = M
 katal = mole / second = kat
 
 # EM
-esu = 1 * erg**0.5 * centimeter**0.5 = statcoulombs = statC = franklin = Fr
-esu_per_second = 1 * esu / second = statampere
+esu = 1 * erg**0.5 * centimeter**0.5 = statcoulomb = statC = franklin = Fr
+esu_per_second = 1 * esu / second = _ = statampere = statA
 ampere_turn = 1 * A
 gilbert = 10 / (4 * pi ) * ampere_turn
 coulomb = ampere * second = C
@@ -96,15 +96,15 @@ henry = weber / ampere = H
 elementary_charge = 1.602176487e-19 * coulomb = e
 chemical_faraday = 9.64957e4 * coulomb
 physical_faraday = 9.65219e4 * coulomb
-faraday =  96485.3399 * coulomb = C12_faraday
+faraday =  96485.3399 * coulomb = _ = C12_faraday
 gamma = 1e-9 * tesla
 gauss = 1e-4 * tesla
-maxwell = 1e-8 * weber = mx
+maxwell = 1e-8 * weber = Mx
 oersted = 1000 / (4 * pi) * A / m = Oe
 statfarad = 1.112650e-12 * farad = statF = stF
 stathenry = 8.987554e11 * henry = statH = stH
 statmho = 1.112650e-12 * siemens = statS = stS
-statohm = 8.987554e11 * ohm
+statohm = 8.987554e11 * ohm = statΩ = stΩ
 statvolt = 2.997925e2 * volt = statV = stV
 unit_pole = 1.256637e-7 * weber
 
@@ -112,17 +112,17 @@ unit_pole = 1.256637e-7 * weber
 [energy] = [force] * [length]
 joule = newton * meter = J
 erg = dyne * centimeter
-btu = 1.05505585262e3 * joule = Btu = BTU = british_thermal_unit
+british_thermal_unit = 1.05505585262e3 * joule = Btu = BTU = btu
 electron_volt = 1.60217653e-19 * J = eV
 quadrillion_btu = 10**15 * btu = quad
-thm = 100000 * BTU = therm = EC_therm
+therm = 100000 * BTU = thm = EC_therm
 calorie = 4.184 * joule = cal = thermochemical_calorie
 international_steam_table_calorie = 4.1868 * joule
 ton_TNT = 4.184e9 * joule = tTNT
 US_therm = 1.054804e8 * joule
 watt_hour = watt * hour = Wh = watthour
-hartree = 4.35974394e-18 * joule = = Eh = E_h = hartree_energy
-toe = 41.868e9 * joule = tonne_of_oil_equivalent
+hartree = 4.35974394e-18 * joule = E_h = Eh = hartree_energy
+tonne_of_oil_equivalent = 41.868e9 * joule = toe
 
 # Force
 [force] = [mass] * [acceleration]
@@ -132,7 +132,7 @@ force_kilogram = g_0 * kilogram = kgf = kilogram_force = pond
 force_gram = g_0 * gram = gf = gram_force
 force_ounce = g_0 * ounce = ozf = ounce_force
 force_pound = g_0 * lb = lbf = pound_force
-force_metric_ton = g_0 * t = metric_ton_force = force_t = t_force
+force_metric_ton = g_0 * t = tf = metric_ton_force = force_t = t_force
 poundal = lb * feet / second ** 2 = pdl
 kip = 1000*lbf
 
@@ -144,7 +144,7 @@ counts_per_second = count / second = cps
 
 # Heat
 #RSI = degK * meter ** 2 / watt
-#clo = 0.155 * RSI = clos
+#clo = 0.155 * RSI = _ = clos
 #R_value = foot ** 2 * degF * hour / btu
 
 # Information
@@ -153,7 +153,7 @@ baud = bit / second = Bd = bps
 
 # Irradiance
 peak_sun_hour = 1000 * watt_hour / meter**2 = PSH
-langley = thermochemical_calorie / centimeter**2 = Langley
+langley = thermochemical_calorie / centimeter**2 = Ly
 
 # Length
 angstrom = 1e-10 * meter = Å = ångström = Å
@@ -164,7 +164,7 @@ astronomical_unit = 149597870691 * meter = au
 # Mass
 carat = 200 * milligram
 metric_ton = 1000 * kilogram = t = tonne
-atomic_mass_unit = 1.660538782e-27 * kilogram =  u = amu = dalton = Da
+atomic_mass_unit = 1.660538782e-27 * kilogram = u = amu = dalton = Da
 bag = 94 * lb
 
 # Textile
@@ -195,13 +195,13 @@ boiler_horsepower = 33475 * btu / hour
 metric_horsepower =  75 * force_kilogram * meter / second
 electric_horsepower = 746 * watt
 hydraulic_horsepower = 550 * feet * lbf / second
-refrigeration_ton = 12000 * btu / hour = ton_of_refrigeration
+refrigeration_ton = 12000 * btu / hour = _ = ton_of_refrigeration
 
 # Pressure
 [pressure] = [force] / [area]
-Hg = gravity * 13.59510 * gram / centimeter ** 3 = mercury = conventional_mercury
+mercury = gravity * 13.59510 * gram / centimeter ** 3 = Hg = conventional_mercury
 mercury_60F = gravity * 13.5568 * gram / centimeter ** 3
-H2O = gravity * 1000 * kilogram / meter ** 3 = h2o = water = conventional_water
+water = gravity * 1000 * kilogram / meter ** 3 = H2O = h2o = conventional_water
 water_4C = gravity * 999.972 * kilogram / meter ** 3 = water_39F
 water_60F = gravity * 999.001 * kilogram / m ** 3
 pascal = newton / meter ** 2 = Pa
@@ -211,31 +211,31 @@ technical_atmosphere = kilogram * gravity / centimeter ** 2 = at
 torr = atm / 760
 pound_force_per_square_inch = pound * gravity / inch ** 2 = psi
 kip_per_square_inch = kip / inch ** 2 = ksi
-barye = 0.1 * newton / meter ** 2 = barie = barad = barrie = baryd = Ba
-mm_Hg = millimeter * Hg = mmHg = millimeter_Hg = millimeter_Hg_0C
-cm_Hg = centimeter * Hg = cmHg = centimeter_Hg
-in_Hg = inch * Hg = inHg = inch_Hg = inch_Hg_32F
+barye = 0.1 * newton / meter ** 2 = Ba = barie = barad = barrie = baryd
+millimeter_Hg = millimeter * Hg = mmHg = mm_Hg = millimeter_Hg_0C
+centimeter_Hg = centimeter * Hg = cmHg = cm_Hg
+inch_Hg = inch * Hg = inHg = in_Hg = inch_Hg_32F
 inch_Hg_60F = inch * mercury_60F
 inch_H2O_39F = inch * water_39F
 inch_H2O_60F = inch * water_60F
-footH2O = ft * water
-cmH2O = centimeter * water
-foot_H2O = ft * water = ftH2O
+centimeter_water = centimeter * water = cmH2O
+foot_H2O = ft * water = ftH2O = footH2O
 standard_liter_per_minute = 1.68875 * Pa * m ** 3 / s = slpm = slm
 
 # Radiation
-Bq = Hz = becquerel
+becquerel = Hz = Bq
 curie = 3.7e10 * Bq = Ci
 rutherford = 1e6*Bq = Rd
-Gy = joule / kilogram = gray = Sv = sievert
+gray = joule / kilogram = Gy
+sievert = joule / kilogram = Sv
 rem = 1e-2 * sievert
 rads = 1e-2 * gray
 roentgen = 2.58e-4 * coulomb / kilogram
 
 # Temperature
-degC = kelvin; offset: 273.15 = celsius
-degR = 5 / 9 * kelvin; offset: 0 = rankine
-degF = 5 / 9 * kelvin; offset: 255.372222 = fahrenheit
+degree_Celsius = kelvin; offset: 273.15 = °C = degC = celsius
+degree_Rankine = 5 / 9 * kelvin; offset: 0 = °R = degR = rankine
+degree_Fahrenheit = 5 / 9 * kelvin; offset: 255.372222 = °F = degF = fahrenheit
 
 # Time
 minute = 60 * second = min
@@ -253,12 +253,12 @@ sidereal_second = sidereal_minute / 60
 sidereal_year = 366.25636042 * sidereal_day
 sidereal_month = 27.321661 * sidereal_day
 tropical_month = 27.321661 * day
-synodic_month = 29.530589 * day = lunar_month
+synodic_month = 29.530589 * day = _ = lunar_month
 common_year = 365 * day
 leap_year = 366 * day
 julian_year = 365.25 * day
 gregorian_year = 365.2425 * day
-millenium = 1000 * year = millenia = milenia = milenium
+millennium = 1000 * year = _ = millennia
 eon = 1e9 * year
 work_year = 2056 * hour
 work_month = work_year / 12
@@ -279,7 +279,7 @@ rhe = 10 / (Pa * s)
 # Volume
 [volume] = [length] ** 3
 liter = 1e-3 * m ** 3 = l = L = litre
-cc = centimeter ** 3 = cubic_centimeter
+cubic_centimeter = centimeter ** 3 = cc
 stere = meter ** 3
 
 
@@ -353,23 +353,23 @@ stere = meter ** 3
     survey_mile = 5280 survey_foot
 
     acre = 43560 survey_foot ** 2
-    square_rod = 1 rod ** 2 = sq_rod = sq_pole = sq_perch
+    square_rod = 1 rod ** 2 = sq_rd = sq_rod = sq_pole = sq_perch
 
     fathom = 6 survey_foot
     us_statute_mile = 5280 survey_foot
     league = 3 us_statute_mile
     furlong = us_statute_mile / 8
 
-    acre_foot = acre * survey_foot = acre_feet
+    acre_foot = acre * survey_foot = _ =acre_feet
 @end
 
 @group USCSDryVolume
-    dry_pint = 33.6003125 cubic_inch  = dpi = US_dry_pint
+    dry_pint = 33.6003125 cubic_inch = dpt = US_dry_pint
     dry_quart = 2 dry_pint = dqt = US_dry_quart
     dry_gallon = 8 dry_pint = dgal = US_dry_gallon
     peck = 16 dry_pint = pk
     bushel = 64 dry_pint = bu
-    dry_barrel = 7056 cubic_inch = US_dry_barrel
+    dry_barrel = 7056 cubic_inch = _ = US_dry_barrel
 @end
 
 @group USCSLiquidVolume
@@ -405,8 +405,8 @@ stere = meter ** 3
     long_hundredweight = 112 avoirdupois_pound = lg_cwt
     short_ton = 2000 avoirdupois_pound
     long_ton = 2240 avoirdupois_pound
-    force_short_ton = short_ton * g_0 = short_ton_force
-    force_long_ton = long_ton * g_0 = long_ton_force
+    force_short_ton = short_ton * g_0 = _ = short_ton_force
+    force_long_ton = long_ton * g_0 = _ = long_ton_force
 @end
 
 @group Troy
@@ -433,14 +433,14 @@ stere = meter ** 3
 @group AvoirdupoisUS using Avoirdupois
     US_hundredweight = short_hundredweight = US_cwt
     US_ton = short_ton = ton
-    US_ton_force = force_short_ton = ton_force = force_ton
+    US_ton_force = force_short_ton = _ = ton_force = force_ton
 @end
 
 @group Printer
     # Length
-    pixel = [printing_unit] = dot = px = pel = picture_element
+    pixel = [printing_unit] = _ = dot = px = pel = picture_element
     pixels_per_centimeter = pixel / cm = PPCM
-    pixels_per_inch = pixel / inch = dots_per_inch = PPI = ppi = DPI = printers_dpi
+    pixels_per_inch = pixel / inch = ppi = dots_per_inch = PPI = DPI = printers_dpi
     bits_per_pixel = bit / pixel = bpp
 
     point = yard / 216 / 12 = pp = printers_point
@@ -450,7 +450,7 @@ stere = meter ** 3
 
 @group ImperialVolume
     imperial_fluid_ounce = imperial_pint / 20 = imperial_floz = UK_fluid_ounce
-    imperial_fluid_drachm = imperial_fluid_ounce / 8 = imperial_fluid_dram
+    imperial_fluid_drachm = imperial_fluid_ounce / 8 = imperial_fldr = imperial_fluid_dram
     imperial_gill = imperial_pint / 4 = imperial_gi = UK_gill
     imperial_cup = imperial_pint / 2 = imperial_cp = UK_cup
     imperial_pint = 568.26125 * milliliter = imperial_pt = UK_pint
diff --git a/pint/definitions.py b/pint/definitions.py
index e8e07c9..e510a1b 100644
--- a/pint/definitions.py
+++ b/pint/definitions.py
@@ -52,9 +52,12 @@ class Definition(object):
                     value.decode('utf-8')
                 except UnicodeEncodeError:
                     result.remove(value)
-        value, aliases = result[0], tuple(result[1:])
+        value, aliases = result[0], tuple([x for x in result[1:] if x != ''])
         symbol, aliases = (aliases[0], aliases[1:]) if aliases else (None,
                                                                      aliases)
+        if symbol == '_':
+            symbol = None
+        aliases = tuple([x for x in aliases if x != '_'])
 
         if name.startswith('['):
             return DimensionDefinition(name, symbol, aliases, value)
diff --git a/pint/registry.py b/pint/registry.py
index 6c9d953..0129ba5 100644
--- a/pint/registry.py
+++ b/pint/registry.py
@@ -279,7 +279,8 @@ class BaseRegistry(meta.with_metaclass(_Meta)):
             else:
                 d_symbol = None
 
-            d_aliases = tuple('Δ' + alias for alias in definition.aliases)
+            d_aliases = tuple('Δ' + alias for alias in definition.aliases) + \
+                        tuple('delta_' + alias for alias in definition.aliases)
 
             d_reference = UnitsContainer(dict((ref, value)
                                          for ref, value in definition.reference.items()))


Test patch:
diff --git a/pint/testsuite/test_definitions.py b/pint/testsuite/test_definitions.py
index 573ee21..3b73fd8 100644
--- a/pint/testsuite/test_definitions.py
+++ b/pint/testsuite/test_definitions.py
@@ -70,6 +70,16 @@ class TestDefinition(BaseTestCase):
         self.assertEqual(x.converter.offset, 255.372222)
         self.assertEqual(x.reference, UnitsContainer(kelvin=1))
 
+        x = Definition.from_string('turn = 6.28 * radian = _ = revolution = = cycle = _')
+        self.assertIsInstance(x, UnitDefinition)
+        self.assertEqual(x.name, 'turn')
+        self.assertEqual(x.aliases, ('revolution', 'cycle'))
+        self.assertEqual(x.symbol, 'turn')
+        self.assertFalse(x.is_base)
+        self.assertIsInstance(x.converter, ScaleConverter)
+        self.assertEqual(x.converter.scale, 6.28)
+        self.assertEqual(x.reference, UnitsContainer(radian=1))
+
     def test_dimension_definition(self):
         x = DimensionDefinition('[time]', '', (), converter='')
         self.assertTrue(x.is_base)