General Converter — v3.0.0#34
Open
aranapatona wants to merge 4 commits intodeefrawley:mainfrom
Open
Conversation
A significant rewrite focused on accuracy, extensibility, and usefulness for technical and scientific work. This release adds 10 new categories, 100+ new units, a cleaner internal architecture, clipboard support, and matching icons for every category.
A significant rewrite focused on accuracy, extensibility, and usefulness for technical and scientific work. This release adds 10 new categories, 100+ new units, a cleaner internal architecture, clipboard support, and matching icons for every category.
Owner
|
A very comprehensive refactor, thank you very much for the work that has gone into this. Can you update the README for the repo to update it with the information above? |
There was a problem hiding this comment.
Pull request overview
This PR delivers the “General Converter” v3.0.0 rewrite by replacing the string/eval-based conversion model with a factor/offset-based engine, expanding unit coverage (new categories + many new units), and adding clipboard-copy support plus new category icons.
Changes:
- Replaced formula-string unit definitions with structured
(abbr, names, factor[, offset])tuples and added a new arithmetic conversion function. - Refactored the plugin query flow to use the new unit schema and added “Enter copies value” clipboard support.
- Added new
.icoassets for the expanded set of categories.
Reviewed changes
Copilot reviewed 2 out of 14 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
plugin/units.py |
Replaces eval-formula units with factor/offset tuples; adds many new categories/units; introduces convert() arithmetic engine. |
plugin/general_converter.py |
Refactors unit lookup and conversion to match the new schema; adds clipboard copy via clip.exe; reorganizes query handling. |
assets/*.ico |
Adds icons for the newly introduced categories. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+124
to
+129
| for cat in get_all_units(): | ||
| title = str(cat[0]) | ||
| subtitle = ", ".join(str(e) for e in cat[1:]) | ||
| icon = f"assets/{title}.ico" | ||
| for line in textwrap.wrap(subtitle, 110, break_long_words=False) or [subtitle]: | ||
| self.add_item(title=title, subtitle=line, icon=icon) |
Comment on lines
+17
to
+23
| def _find_unit(abbr: str): | ||
| """Return (category_key, unit_tuple) or (None, None).""" | ||
| for cat_key, cat in gc_units.units.items(): | ||
| for u in cat["units"]: | ||
| if abbr in (u[0], u[1], u[2]): | ||
| return cat_key, u | ||
| return None, None |
Comment on lines
+41
to
+44
| cat_key, _ = _find_unit(from_unit) | ||
| if not cat_key: | ||
| return [_("no valid units")] | ||
| return [u[0] for u in gc_units.units[cat_key]["units"] if u[0] != from_unit] |
Comment on lines
+77
to
+82
| s = str(amount) | ||
| dec_places = s[::-1].find(separator) | ||
| if dec_places == -1: | ||
| return 0 | ||
| frac = s[-dec_places:] | ||
| if int(frac) == 0: |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
General Converter — v3.0.0
⚡ What's New at a Glance
eval()on formula strings🆕 New Categories
Force
N·mN·kN·MN·dyn·kgf·lbf·pdlNewton, millinewton, kilonewton, meganewton, dyne, kilogram-force, pound-force, poundal.
Power
W·mW·kW·MW·GW·hp·hpmet·BTU/hr·kcal/hr·VAWatt through gigawatt, mechanical and metric horsepower, BTU/hr, kilocalorie/hr, volt-ampere.
Torque
Nm·kNm·mNm·lbf_ft·lbf_in·kgfm·ozf_in·dyn_cmNewton-metre through millinewton-metre, pound-foot, pound-inch, kilogram-force metre, ounce-force inch, dyne-centimetre.
Frequency
Hz·kHz·MHz·GHz·THz·rpm·rps·rad/sHertz through terahertz, RPM, revolutions per second, radians per second.
Angle
deg·rad·grad·arcmin·arcsec·rev·mradDegree, radian, gradian, arcminute, arcsecond, revolution, milliradian.
Amount of Substance
mol·mmol·µmol·nmol·pmol·kmolMole through picomole and kilomole. Essential for chemistry and biochemistry.
Radioactivity
Bq·kBq·MBq·GBq·TBq·Ci·mCi·µCi·nCi·dpmBecquerel through terabecquerel, curie through nanocurie, disintegrations per minute.
Radiation Dose (absorbed)
Gy·mGy·µGy·cGy·rad·mradGray, milligray, microgray, centigray, rad, millirad.
Dose Equivalent
Sv·mSv·µSv·rem·mremSievert, millisievert, microsievert, rem, millirem.
Density
kg/m3·g/cm3·g/mL·kg/L·g/L·mg/L·lb/ft3·lb/in3·lb/galSI and imperial density units, including g/mL and mg/L common in chemistry and lab work.
Dynamic Viscosity
Pa_s·mPa_s·cP·P·lb/ft_sPascal-second, millipascal-second, centipoise, poise, pound per foot-second.
Kinematic Viscosity
m2/s·mm2/s·cSt·St·ft2/sSquare metre per second, square millimetre per second, centistokes, stokes, square foot per second.
🔧 Expanded Existing Categories
Distance
Added:
µm(micrometre),nm(nanometre),Å(ångström),nmi(nautical mile),ly(light-year),au(astronomical unit),pc(parsec)Area
Added:
sqmm(square millimetre)Volume
Added:
cl(centilitre),dl(decilitre)Weight / Mass
Added:
mg(milligram),µg(microgram),ng(nanogram),Da(dalton),u(atomic mass unit)Temperature
Added:
r(Rankine) — used in thermodynamics and aerospace engineeringSpeed
Added:
ft/s(feet per second),mach(Mach number at sea level, 15°C),c(speed of light)Energy
Added:
mJ(millijoule),MWh(megawatt-hour),therm,eV/keV/MeV/GeV(electronvolts),ergPressure
Rebuilt with Pa as base (was
bar). Added:hPa(hectopascal),MPa,GPa,ksi,mmHg,Torr,inHg🐛 Bug Fixes in Existing Units
These were silent wrong-answer bugs in v2.1.0:
mm3÷ 0.1→ ×10 ml÷ 1000→ 0.001 ml ✓sqkm÷ 1,000,000→ 0.000001 m²× 1,000,000→ 1,000,000 m² ✓gkPaSpelling fix:
Farenheit→FahrenheitCapitalisation fix:
Gj→GJ(gigajoule)✨ Clipboard Support
Pressing Enter on a conversion result now copies the converted value to the clipboard. The value is copied without thousands separators so it pastes cleanly into calculations, spreadsheets, or code.
🏗️ Internal Architecture
Why the format changed
The old
units.pystored conversions as a pair of formula strings that wereeval()'d at runtime:This had several problems:
"x / 0.001"is less readable than1_000(1 km = 1000 m)eval()on user-facing data is a security surfaceNew format — linear units
Each unit is a 4-tuple:
(abbreviation, singular, plural, factor)The factor is the answer to: "how many base units make up one of this unit?"
The engine converts any pair using only two multiplications — no strings, no eval:
New format — affine units (Temperature)
Units that don't convert via a simple ratio (Temperature, Rankine) use a 5-tuple with an extra
offsetfield:The engine detects the 5-tuple and applies the affine formula:
The offset encodes what you add to the raw value before scaling. For Fahrenheit: add −32 (i.e. subtract 32), then divide by 1.8. This matches the standard formula exactly and handles round-trips correctly.
Adding your own units
Add a unit to an existing category — append a tuple to the
"units"list. The factor is simply "how many base units equal one of this unit":Add a brand new category:
Then add a corresponding
assets/My Category.ico(128×128 RGBA, transparent background).📋 Full Unit Reference
Units are case-sensitive. Base unit listed first for each category.
Distance (base: m)
mdmcmmmµmnmkminftydminmilyaupcÅArea (base: sqm)
sqmsqcmsqmmsqkmsqinsqftsqydsqmiachVolume (base: ml)
mlcldlldecalm3cm3mm3dm3in3ft3pt/ptimpqt/qtimpcup/cupimptbsp/tbspimptsp/tspimpgal/galimpfloz/flozimpbuuk/buusWeight / Mass (base: g)
gmgµgngkgtlbozsttontonimpDauTemperature (base: c)
cfkrSpeed (base: m/s)
m/skm/hmp/hft/sktmachcForce (base: N)
NmNkNMNdynkgflbfpdlPressure (base: Pa)
PahPakPaMPaGPabarmbaratmmmHgtorrpsiksiinHgEnergy (base: J)
JmJkJMJGJcalkcalkWhMWhBTUthermeVkeVMeVGeVergPower (base: W)
WmWkWMWGWhphpmetBTU/hrkcal/hrVATorque (base: Nm)
NmkNmmNmlbf_ftlbf_inkgfmozf_indyn_cmFrequency (base: Hz)
HzkHzMHzGHzTHzrpmrpsrad/sAngle (base: deg)
degradgradarcminarcsecrevmradAmount of Substance (base: mol)
molmmolµmolnmolpmolkmolRadioactivity (base: Bq)
BqkBqMBqGBqTBqCimCiµCinCidpmRadiation Dose (base: Gy)
GymGyµGycGyradmradDose Equivalent (base: Sv)
SvmSvµSvremmremDensity (base: kg/m3)
kg/m3g/cm3g/mLkg/Lg/Lmg/Llb/ft3lb/in3lb/galDynamic Viscosity (base: Pa_s)
Pa_smPa_scPPlb/ft_sKinematic Viscosity (base: m2/s)
m2/smm2/scStStft2/sData (base: B)
BKBMBGBTBPBbKbMbGbTbPbKiBMiBGiBTiBPiBKibMibGibTibPib🙏 Credits
Original plugin by @deefrawley.
v3.0.0 expansion and refactor contributed by the community.