rda-python-common 3.0.7__tar.gz → 3.0.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rda_python_common-3.0.7/src/rda_python_common.egg-info → rda_python_common-3.0.10}/PKG-INFO +1 -1
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/pyproject.toml +1 -1
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_dbi.py +103 -23
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_file.py +28 -4
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_opt.py +3 -3
- {rda_python_common-3.0.7 → rda_python_common-3.0.10/src/rda_python_common.egg-info}/PKG-INFO +1 -1
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/LICENSE +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/README.md +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/setup.cfg +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgCMD.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgDBI.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgFile.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgLOG.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgLock.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgOPT.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgSIG.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgSplit.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/PgUtil.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/__init__.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_cmd.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_lock.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_log.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_password.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_sig.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_split.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pg_util.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pgpassword.py +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common/pgpassword.usg +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/SOURCES.txt +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/dependency_links.txt +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/entry_points.txt +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/requires.txt +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/top_level.txt +0 -0
- {rda_python_common-3.0.7 → rda_python_common-3.0.10}/test/test_common.py +0 -0
{rda_python_common-3.0.7/src/rda_python_common.egg-info → rda_python_common-3.0.10}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_common
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.10
|
|
4
4
|
Summary: RDA Python common library codes shared by other RDA python packages
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-common
|
|
@@ -85,6 +85,7 @@ class PgDBI(PgLOG):
|
|
|
85
85
|
curtran (int): Transaction counter: 0 = idle, >0 = inside a transaction.
|
|
86
86
|
NMISSES (list): Cached list of scientist IDs (userno) not found in the DB.
|
|
87
87
|
LMISSES (list): Cached list of login names not found in the DB.
|
|
88
|
+
USRWARN (int): Set to 1 once the 'run filluser' reminder has been logged.
|
|
88
89
|
TABLES (dict): Cache of table-field default info keyed by table name.
|
|
89
90
|
SEQUENCES (dict): Cache of sequence field names keyed by table name.
|
|
90
91
|
SPECIALIST (dict): Cache of specialist records keyed by dataset ID.
|
|
@@ -125,6 +126,7 @@ class PgDBI(PgLOG):
|
|
|
125
126
|
self.curtran = 0 # 0 - no transaction, 1 - in transaction
|
|
126
127
|
self.NMISSES = [] # array of mising userno
|
|
127
128
|
self.LMISSES = [] # array of mising logname
|
|
129
|
+
self.USRWARN = 0 # 1 - reminder for incomplete user records given already
|
|
128
130
|
self.TABLES = {} # record table field information
|
|
129
131
|
self.SEQUENCES = {} # record table sequence fielnames
|
|
130
132
|
self.SPECIALIST = {} # hash array refrences to specialist info of dsids
|
|
@@ -1699,6 +1701,82 @@ class PgDBI(PgLOG):
|
|
|
1699
1701
|
ret = self.pgget('information_schema.tables', None, condition, logact)
|
|
1700
1702
|
return (self.SUCCESS if ret else self.FAILURE)
|
|
1701
1703
|
|
|
1704
|
+
def dssgrp_user_info(self, userno, logname = None):
|
|
1705
|
+
"""Build a partial dssdb.user record from dssdb.dssgrp.
|
|
1706
|
+
|
|
1707
|
+
Fallback for when the UCAR People API is unreachable, so a usable user record
|
|
1708
|
+
can still be added for a DECS group member. Fields absent from dssgrp are set
|
|
1709
|
+
to the values implied by DECS membership; the record is marked stat_flag 'M'
|
|
1710
|
+
so that 'filluser -i' completes it once the People API is available again.
|
|
1711
|
+
|
|
1712
|
+
Args:
|
|
1713
|
+
userno (int): Scientist number; pass 0 to look up by logname instead.
|
|
1714
|
+
logname (str | None): UCAR login name; used when userno is 0.
|
|
1715
|
+
|
|
1716
|
+
Returns:
|
|
1717
|
+
dict | None: Partial mapping of column_name → value suitable for
|
|
1718
|
+
pgadd('dssdb.user'), or None when not in dssgrp.
|
|
1719
|
+
"""
|
|
1720
|
+
cond = "userno = {}".format(userno) if userno else "logname = '{}'".format(logname)
|
|
1721
|
+
pgrec = self.pgget("dssgrp", "logname, userno, lstname, fstname, midinit, phoneno", cond, self.PGDBI['ERRLOG'])
|
|
1722
|
+
if not pgrec: return None
|
|
1723
|
+
if not pgrec['userno']: del pgrec['userno'] # leave NULL; 0 is never looked up
|
|
1724
|
+
email = pgrec['logname'] + '@ucar.edu'
|
|
1725
|
+
pgrec['org_type'] = 'DSS'
|
|
1726
|
+
pgrec['org_name'] = 'NCAR'
|
|
1727
|
+
pgrec['country'] = 'UNITED.STATES'
|
|
1728
|
+
pgrec['email'] = pgrec['ucaremail'] = email
|
|
1729
|
+
pgrec['stat_flag'] = 'M'
|
|
1730
|
+
return pgrec
|
|
1731
|
+
|
|
1732
|
+
def add_missed_user(self, userno, logname = None):
|
|
1733
|
+
"""Add a dssdb.user record for a user missing from the table.
|
|
1734
|
+
|
|
1735
|
+
Tries the UCAR People API first, then dssgrp, and finally falls back to a bare
|
|
1736
|
+
stub. A reminder to run filluser is logged once per process whenever the added
|
|
1737
|
+
record is incomplete (stat_flag 'M').
|
|
1738
|
+
|
|
1739
|
+
Args:
|
|
1740
|
+
userno (int): Scientist number; pass 0 to add by logname instead.
|
|
1741
|
+
logname (str | None): UCAR login name; used when userno is 0.
|
|
1742
|
+
|
|
1743
|
+
Returns:
|
|
1744
|
+
int: The new user.uid, or 0 if the insert fails.
|
|
1745
|
+
"""
|
|
1746
|
+
pgrec = self.ucar_user_info(userno, logname)
|
|
1747
|
+
if not pgrec: pgrec = self.dssgrp_user_info(userno, logname)
|
|
1748
|
+
if not pgrec:
|
|
1749
|
+
pgrec = {'userno': userno} if userno else {'logname': logname}
|
|
1750
|
+
pgrec['stat_flag'] = 'M'
|
|
1751
|
+
if pgrec['stat_flag'] == 'M': self.incomplete_user_warning()
|
|
1752
|
+
return self.pgadd("dssdb.user", pgrec, (self.PGDBI['EXITLG']|self.AUTOID))
|
|
1753
|
+
|
|
1754
|
+
def incomplete_user_warning(self):
|
|
1755
|
+
"""Log a one-time reminder to run filluser for incomplete dssdb.user records."""
|
|
1756
|
+
if self.USRWARN: return
|
|
1757
|
+
self.USRWARN = 1
|
|
1758
|
+
self.pglog("Incomplete record in dssdb.user; run 'filluser -i' later to complete it", self.LGWNEM)
|
|
1759
|
+
|
|
1760
|
+
def reopen_user_record(self, pgrec):
|
|
1761
|
+
"""Reactivate a closed dssdb.user record and return its uid.
|
|
1762
|
+
|
|
1763
|
+
Clears until_date and marks the record incomplete (stat_flag 'M') so that
|
|
1764
|
+
'filluser -i' refreshes it. Records that are not closed are returned as is.
|
|
1765
|
+
Only call this for a present-day lookup; reopening on a historical lookup
|
|
1766
|
+
would wrongly reactivate a user who has since left.
|
|
1767
|
+
|
|
1768
|
+
Args:
|
|
1769
|
+
pgrec (dict): Record holding at least 'uid' and 'until_date'.
|
|
1770
|
+
|
|
1771
|
+
Returns:
|
|
1772
|
+
int: The uid of the record.
|
|
1773
|
+
"""
|
|
1774
|
+
if pgrec['until_date']:
|
|
1775
|
+
record = {'until_date': None, 'stat_flag': 'M'}
|
|
1776
|
+
self.pgupdt("dssdb.user", record, "uid = {}".format(pgrec['uid']), self.PGDBI['ERRLOG'])
|
|
1777
|
+
self.pglog("Closed user.uid = {} is reopened".format(pgrec['uid']), self.LGWNEM)
|
|
1778
|
+
return pgrec['uid']
|
|
1779
|
+
|
|
1702
1780
|
def check_user_uid(self, userno, date = None):
|
|
1703
1781
|
"""Return the user.uid for a scientist ID, adding a record if missing.
|
|
1704
1782
|
|
|
@@ -1716,6 +1794,7 @@ class PgDBI(PgLOG):
|
|
|
1716
1794
|
"""
|
|
1717
1795
|
if not userno: return 0
|
|
1718
1796
|
if type(userno) is str: userno = int(userno)
|
|
1797
|
+
istoday = (date is None)
|
|
1719
1798
|
if date is None:
|
|
1720
1799
|
datecond = "until_date IS NULL"
|
|
1721
1800
|
date = 'today'
|
|
@@ -1727,11 +1806,9 @@ class PgDBI(PgLOG):
|
|
|
1727
1806
|
self.pglog("{}: Scientist ID NOT on file for {}".format(userno, date), self.LGWNEM)
|
|
1728
1807
|
self.NMISSES.append(userno)
|
|
1729
1808
|
# check again if a user is on file with different date range
|
|
1730
|
-
pgrec = self.pgget("dssdb.user", "uid", "userno = {}".format(userno), self.PGDBI['ERRLOG'])
|
|
1731
|
-
if pgrec: return pgrec['uid']
|
|
1732
|
-
|
|
1733
|
-
if not pgrec: pgrec = {'userno': userno, 'stat_flag': 'M'}
|
|
1734
|
-
uid = self.pgadd("dssdb.user", pgrec, (self.PGDBI['EXITLG']|self.AUTOID))
|
|
1809
|
+
pgrec = self.pgget("dssdb.user", "uid, until_date", "userno = {}".format(userno), self.PGDBI['ERRLOG'])
|
|
1810
|
+
if pgrec: return self.reopen_user_record(pgrec) if istoday else pgrec['uid']
|
|
1811
|
+
uid = self.add_missed_user(userno)
|
|
1735
1812
|
if uid: self.pglog("{}: Scientist ID Added as user.uid = {}".format(userno, uid), self.LGWNEM)
|
|
1736
1813
|
return uid
|
|
1737
1814
|
|
|
@@ -1748,6 +1825,7 @@ class PgDBI(PgLOG):
|
|
|
1748
1825
|
int: user.uid on success, 0 if logname is falsy or insert fails.
|
|
1749
1826
|
"""
|
|
1750
1827
|
if not logname: return 0
|
|
1828
|
+
istoday = (not date)
|
|
1751
1829
|
if not date:
|
|
1752
1830
|
date = 'today'
|
|
1753
1831
|
datecond = "until_date IS NULL"
|
|
@@ -1759,11 +1837,9 @@ class PgDBI(PgLOG):
|
|
|
1759
1837
|
self.pglog("{}: UCAR Login Name NOT on file for {}".format(logname, date), self.LGWNEM)
|
|
1760
1838
|
self.LMISSES.append(logname)
|
|
1761
1839
|
# check again if a user is on file with different date range
|
|
1762
|
-
pgrec = self.pgget("dssdb.user", "uid", "logname = '{}'".format(logname), self.PGDBI['ERRLOG'])
|
|
1763
|
-
if pgrec: return pgrec['uid']
|
|
1764
|
-
|
|
1765
|
-
if not pgrec: pgrec = {'logname': logname, 'stat_flag': 'M'}
|
|
1766
|
-
uid = self.pgadd("dssdb.user", pgrec, (self.PGDBI['EXITLG']|self.AUTOID))
|
|
1840
|
+
pgrec = self.pgget("dssdb.user", "uid, until_date", "logname = '{}'".format(logname), self.PGDBI['ERRLOG'])
|
|
1841
|
+
if pgrec: return self.reopen_user_record(pgrec) if istoday else pgrec['uid']
|
|
1842
|
+
uid = self.add_missed_user(0, logname)
|
|
1767
1843
|
if uid: self.pglog("{}: UCAR Login Name Added as user.uid = {}".format(logname, uid), self.LGWNEM)
|
|
1768
1844
|
return uid
|
|
1769
1845
|
|
|
@@ -1796,6 +1872,9 @@ class PgDBI(PgLOG):
|
|
|
1796
1872
|
'email': "ucaremail",
|
|
1797
1873
|
'phone': "phoneno"
|
|
1798
1874
|
}
|
|
1875
|
+
# pgperson/pgusername are installed by rda_python_metrics; skip quietly when the
|
|
1876
|
+
# commands are not on this host so that callers can fall back to dssgrp
|
|
1877
|
+
if not self.valid_command("pgperson"): return None
|
|
1799
1878
|
buf = self.pgsystem("pgperson " + ("-uid {}".format(userno) if userno else "-username {}".format(logname)), self.LOGWRN, 20)
|
|
1800
1879
|
if not buf: return None
|
|
1801
1880
|
pgrec = {}
|
|
@@ -1807,23 +1886,24 @@ class PgDBI(PgLOG):
|
|
|
1807
1886
|
if key == 'upid' and 'upid' in pgrec: break # get one record only
|
|
1808
1887
|
pgrec[matches[key]] = val
|
|
1809
1888
|
if not pgrec: return None
|
|
1889
|
+
# the People API omits keys it has no value for, so read them defensively
|
|
1810
1890
|
if userno:
|
|
1811
1891
|
pgrec['userno'] = userno
|
|
1812
|
-
elif pgrec
|
|
1892
|
+
elif pgrec.get('userno'):
|
|
1813
1893
|
pgrec['userno'] = userno = int(pgrec['userno'])
|
|
1814
|
-
if pgrec
|
|
1815
|
-
if pgrec
|
|
1816
|
-
|
|
1817
|
-
|
|
1894
|
+
if pgrec.get('upid'): pgrec['upid'] = int(pgrec['upid'])
|
|
1895
|
+
if pgrec.get('stat_flag'): pgrec['stat_flag'] = 'A' if pgrec['stat_flag'] == "True" else 'C'
|
|
1896
|
+
email = pgrec.get('email')
|
|
1897
|
+
if email and re.search(r'(@|\.)ucar\.edu$', email, re.I):
|
|
1898
|
+
email = pgrec['email'] = pgrec.get('ucaremail')
|
|
1818
1899
|
pgrec['org_name'] = 'NCAR'
|
|
1819
|
-
country = pgrec
|
|
1820
|
-
pgrec['country'] = self.set_country_code(
|
|
1821
|
-
if pgrec
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
buf = self.pgsystem("pgusername {}".format(pgrec['logname']), self.LOGWRN, 20)
|
|
1900
|
+
country = pgrec.get('country')
|
|
1901
|
+
if email or country: pgrec['country'] = self.set_country_code(email, country)
|
|
1902
|
+
val = "NCAR" if pgrec.get('division') else None
|
|
1903
|
+
pgrec['org_type'] = self.get_org_type(val, email)
|
|
1904
|
+
logname = pgrec.get('logname')
|
|
1905
|
+
if not logname or not self.valid_command("pgusername"): return pgrec
|
|
1906
|
+
buf = self.pgsystem("pgusername {}".format(logname), self.LOGWRN, 20)
|
|
1827
1907
|
if not buf: return pgrec
|
|
1828
1908
|
for line in buf.split('\n'):
|
|
1829
1909
|
ms = re.match(r'^(.+)<=>(.*)$', line)
|
|
@@ -233,9 +233,9 @@ class PgFile(PgUtil, PgSIG):
|
|
|
233
233
|
if self.pgcmp(thost, self.OHOST, 1) == 0:
|
|
234
234
|
return self.local_copy_object(tofile, fromfile, None, None, logact)
|
|
235
235
|
elif self.pgcmp(thost, self.BHOST, 1) == 0:
|
|
236
|
-
return self.
|
|
236
|
+
return self.wait_copy_backup(tofile, fromfile, self.QPOINTS['B'], logact)
|
|
237
237
|
elif self.pgcmp(thost, self.DHOST, 1) == 0:
|
|
238
|
-
return self.
|
|
238
|
+
return self.wait_copy_backup(tofile, fromfile, self.QPOINTS['D'], logact)
|
|
239
239
|
else:
|
|
240
240
|
return self.local_copy_remote(tofile, fromfile, tohost, logact)
|
|
241
241
|
elif self.pgcmp(thost, self.LHOST, 1) == 0:
|
|
@@ -664,6 +664,25 @@ class PgFile(PgUtil, PgSIG):
|
|
|
664
664
|
if not endpoint: endpoint = self.PGLOG['BACKUPEP']
|
|
665
665
|
return self.endpoint_copy_endpoint(tofile, fromfile, endpoint, 'gdex-glade', logact)
|
|
666
666
|
|
|
667
|
+
# Copy a local file to Quasar backup tape system and wait until the Globus task is done
|
|
668
|
+
# for callers that cannot handle a self.FINISH return
|
|
669
|
+
def wait_copy_backup(self, tofile, fromfile, endpoint = None, logact = 0):
|
|
670
|
+
"""Copy a local GLADE file to the Quasar backup endpoint and wait for completion.
|
|
671
|
+
|
|
672
|
+
Args:
|
|
673
|
+
tofile (str): Destination path on the backup endpoint (leading '/dsNNN.N/').
|
|
674
|
+
fromfile (str): Source local path (leading '/data/' or '/decsdata/').
|
|
675
|
+
endpoint (str | None): Globus endpoint name; defaults to PGLOG['BACKUPEP'].
|
|
676
|
+
logact (int): Logging action flags; default 0.
|
|
677
|
+
|
|
678
|
+
Returns:
|
|
679
|
+
int: self.SUCCESS or self.FAILURE.
|
|
680
|
+
"""
|
|
681
|
+
if not endpoint: endpoint = self.PGLOG['BACKUPEP']
|
|
682
|
+
ret = self.local_copy_backup(tofile, fromfile, endpoint, logact)
|
|
683
|
+
if ret == self.FINISH: ret = self.check_globus_finished(tofile, endpoint, logact)
|
|
684
|
+
return ret
|
|
685
|
+
|
|
667
686
|
# Copy a Quasar backup file to local Globus endpoint
|
|
668
687
|
# tofile - target file name, leading with /data/ or /decsdata/
|
|
669
688
|
# fromfile - source file name, leading with /dsnnn.n/
|
|
@@ -671,6 +690,9 @@ class PgFile(PgUtil, PgSIG):
|
|
|
671
690
|
def backup_copy_local(self, tofile, fromfile, endpoint = None, logact = 0):
|
|
672
691
|
"""Copy a file from the Quasar backup endpoint to a local GLADE path via Globus.
|
|
673
692
|
|
|
693
|
+
Waits for the Globus task to finish before returning, so the local file is
|
|
694
|
+
complete for the caller.
|
|
695
|
+
|
|
674
696
|
Args:
|
|
675
697
|
tofile (str): Destination local path (leading '/data/' or '/decsdata/').
|
|
676
698
|
fromfile (str): Source backup path (leading '/dsNNN.N/').
|
|
@@ -678,10 +700,12 @@ class PgFile(PgUtil, PgSIG):
|
|
|
678
700
|
logact (int): Logging action flags; default 0.
|
|
679
701
|
|
|
680
702
|
Returns:
|
|
681
|
-
int: self.SUCCESS
|
|
703
|
+
int: self.SUCCESS or self.FAILURE.
|
|
682
704
|
"""
|
|
683
705
|
if not endpoint: endpoint = self.PGLOG['BACKUPEP']
|
|
684
|
-
|
|
706
|
+
ret = self.endpoint_copy_endpoint(tofile, fromfile, 'gdex-glade', endpoint, logact)
|
|
707
|
+
if ret == self.FINISH: ret = self.check_globus_finished(tofile, 'gdex-glade', logact)
|
|
708
|
+
return ret
|
|
685
709
|
|
|
686
710
|
# Copy a remote file to local
|
|
687
711
|
# tofile - target file name
|
|
@@ -577,9 +577,9 @@ class PgOPT(PgFile):
|
|
|
577
577
|
if 'LN' not in self.params: self.pglog("Could not get user login name", self.PGOPT['extlog'])
|
|
578
578
|
self.validate_dataset()
|
|
579
579
|
if self.OPTS[self.PGOPT['CACT']][2] > 0: self.validate_dsowner(aname)
|
|
580
|
-
|
|
581
|
-
if not
|
|
582
|
-
self.PGOPT['UID'] =
|
|
580
|
+
uid = self.get_user_uid(self.params['LN'])
|
|
581
|
+
if not uid: self.pglog("Could not get user.uid for " + self.params['LN'], self.PGOPT['extlog'])
|
|
582
|
+
self.PGOPT['UID'] = uid
|
|
583
583
|
self.open_output(self.params['OF'] if 'OF' in self.params else None)
|
|
584
584
|
|
|
585
585
|
def set_sudo_uid(self, aname, uid):
|
{rda_python_common-3.0.7 → rda_python_common-3.0.10/src/rda_python_common.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_common
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.10
|
|
4
4
|
Summary: RDA Python common library codes shared by other RDA python packages
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-common
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/requires.txt
RENAMED
|
File without changes
|
{rda_python_common-3.0.7 → rda_python_common-3.0.10}/src/rda_python_common.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|